【发布时间】:2015-04-01 19:30:23
【问题描述】:
我正在尝试编写一个宏,以便仅在某些环境中有条件地将 compojure 处理程序包装在中间件中。我似乎迷失了评估顺序以及我应该引用什么/如何引用。我目前的尝试如下:
(defn empty-middleware [handler]
(fn [request] (handler request)))
(defmacro prod [handler middleware]
(if (= "production" (System/getenv "APP_ENV"))
(middleware handler)
(empty-middleware handler)))
期望的用法是:
(in/prod (fn [handler] (airbrake/wrap-airbrake handler config/airbrake-api-key)))
--- 编辑 ---
更多信息: in/prod 应该在线程宏内部使用,该宏将路由包装在许多中间件中,例如:
(-> handler
middleware1
middleware2
(in/prod (middleware3 middleware-3-param1))
middleware3 和 in/prod 都需要 handler 作为参数。在括号中包装 middleware3 评估不可能将处理程序作为参数传递。因此,我认为需要一个宏。我想出了如何制作/生产一个将中间件3和中间件参数作为参数传递的函数:
(defn prod [handler middleware & middleware-params]
(if (= "production" (System/getenv "APP_ENV"))
(apply middleware handler middleware-params)
handler))
虽然它稍微改变了语法。调用看起来像:
(-> handler
middleware1
middleware2
(in/prod middleware3 middleware-3-param1)
如何才能使用如下语法:
(in/prod (middleware3 middleware-3-param1)
【问题讨论】:
-
我看不出有什么理由在这里使用宏。您能否提供更多详细信息,说明为什么这必须是宏而不是返回处理程序的
fn? -
好吧,也许不是。最初我的想法是我需要宏而不是评估中间件。那是在我将它包装在函数中之前。理想情况下,我希望能够不将“airbrake/wrap-airbrake”包装在函数中,也就是样板更少。
-
希望的用法不是更像:
(in/prod (airbrake/wrap-airbrake handler config/airbrake-api-key))?根据您的使用,您可以简单地使用一个函数。而prod需要两个参数,而你只传递了一个,这是错字吗?
标签: macros clojure lisp compojure