2024年 Clojure 状态问卷中分享您的想法!

欢迎!请查阅关于页面了解有关如何使用本站的一些更多信息。

0
Clojure

我有几个请求处理器,它们都遵循一个类似的模式。


(defn handle-data-1
  [req]
  {:pre [(some? req)]}
  (try
    (let [start-date (parse-query-param (-> req :params :start-date))
          end-date (parse-query-param (-> req :params :end-date))
          data (db/fetch-data-1 start-date end-date)
          data-count (count data)]
      (log/debugf "data-count=%d start-date=%s end-date=%s" data-count start-date end-date)
      (if (pos? data-count)
        {:status 200
         :body data}
        {:status 404}))
    (catch Exception e
      (let [error-message (.getMessage e)]
        (log/errorf "%s" error-message)
        {:status 500 :body error-message}))))

(defn handle-data-2
  [req]
  {:pre [(some? req)]}
  (try
    (let [limit (Long/valueOf (parse-query-param (-> req :params :limit)))
          data (db/fetch-data-2 limit)
          data-count (count data)]
      (if (pos? data-count)
        {:status 200
         :body data}
        {:status 404}))
    (catch Exception e
      (let [error-message (.getMessage e)]
        (log/errorf "%s" error-message)
        {:status 500 :body error-message}))))

(defn handle-data-3
  [_]
  (try
    (let [data (db/fetch-data-3)
          data-count (count data)]
      (log/debugf "data-count=%d" data-count)
      (if (pos? data-count)
        {:status 200
         :body data}
        {:status 404}))
    (catch Exception e
      (let [error-message (.getMessage e)]
        (log/errorf "%s" error-message)
        {:status 500 :body error-message}))))

我正在尝试创建一个通用函数,该函数可以被所有的处理函数使用。例如:


(defn try-query [f]
  {:pre [(some? f)]}
  (try
    (let [data (f) ;; <- need to invoke function and store results in data
          data-count (count data)]
      (if (pos? data-count)
        {:status 200
         :body data}
        {:status 404}))
    (catch Exception e
      (let [error-message (.getMessage e)]
        (log/errorf "%s" error-message)
        {:status 500 :body error-message}))))

(defn handle-data-1 [req]
  (let [start-date (parse-query-param (-> req :params :start-date))
        end-date (parse-query-param (-> req :params :end-date))]
    (log/debugf "start-date=%s end-date=%s" start-date end-date)
    (try-query (fn [] (db/fetch-data-1 start-date end-date))))) ;; 

通用函数需要接受另一个函数(或闭包)作为参数,并且具有可变的arity。我希望这个通用函数可以调用传入的函数,并将其结果存储在变量中。

在 Ruby 中,我可以通过在一个函数中传递一个 lambda,然后在函数中调用它来实现这一点。我不确定如何在 Clojure 中实现这一点。

有任何想法吗?


编辑
现在它已经正常工作了。我相信原始的错误`无法打开 nil 作为 Reader`是由于在调用链中遗漏了 deref 引起的。

我已经将函数移动到 let 中来整理一下。

(defn handle-data-1 [req]
  (let [start-date (parse-query-param (-> req :params :start-date))
        end-date (parse-query-param (-> req :params :end-date))
        query-fn (fn [] (db/fetch-data-1 start-date end-date))
    (log/debugf "start-date=%s end-date=%s" start-date end-date)
    (try-query query-fn))))

1 答案

0
by

当你运行此代码时是否看到错误?没有缺少的上下文很难知道。无论如何,只要“try-query”中的参数f是一个函数,那么形式(f)将会调用它。

by
是的:`Cannot open <nil> as a Reader.` 我也尝试了直接的方法,错误相同。
by
我认为这个错误是由于在调用链更高一级的地方遗漏了解引用导致的。
...