Clojure中的宏,评估和引用
我试图编写一个宏,只在特定的环境中有条件地将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))
中间件3和in / prod都需要处理程序作为参数。 在括号中包装中间件3时,不会将处理程序作为参数传递。 因此我认为需要一个宏。 我研究了如何制作/生成一个传递中间件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)
如果您希望应用的中间件也是宏,那么您可能需要将其作为宏,因此您正在遭受宏观传染。 在这种情况下,您只需要一个返回两个可能的s-expressins中的一个的宏来包含在生成的代码中。 其中一个处理程序直接被调用,另一个被包装在给定的中间件中。
(defmacro prod [handler middleware]
(if (= "production" (System/getenv "APP_ENV"))
`(~middleware ~handler) ;; or (list middleware handler)
handler))
如果您目前没有受到宏观感染,而无法通过在其他地方删除宏来解决这个问题,那么您不需要使用这样的宏,并且您示例中的代码可以简单地用作函数而不是宏。 在任何情况下都不需要空中间件位。
链接地址: http://www.djcxy.com/p/65765.html