我有这个功能:
(defn handler [request]
(case (request :uri)
"/" (home request)
"/good" (good request)
"/evil" (evil request)
"/neutral" (neutral request)
(status-response 404 (str "<h1>404 Not Found: " (:uri request) "</h1>" ))))
但我不断更改页面列表 - 解析为同名的函数,我希望能够写出来:
(def-handler good evil neutral)
代替:
但我被困住了。到目前为止,我最好的镜头看起来像:
(defmacro def-handler [& addresses]
`(defn handler [request#]
(case (request# :uri)
~@(mapcat (fn[x] [(str "/" x) (list x 'request)]) addresses)
"/" (home request#)
(status-response 404 (str "<h1>404 Not Found: " (:uri request#) "</h1>" )))))
但它不太有用,因为生成的调用中的请求不是gensym,我不知道如何在那里获得gensym。
这看起来很有希望,直到我注意到它成了一个新的gensym:
(defmacro def-handler [& addresses]
`(defn handler [request#]
(case (request# :uri)
~@(mapcat (fn[x] [(str "/" x) `( ~x request#)]) addresses)
"/" (home request#)
(status-response 404 (str "<h1>404 Not Found: " (:uri request#) "</h1>" )))))
答案 0 :(得分:3)
我认为你可以在这里避免使用gensym。我不知道你怎么能污染&#34;不使用gensym的环境。没有gensym的例子:
(defmacro def-handler [& addresses]
`(defn handler [~'request]
(case (~'request :uri)
~@(mapcat (fn[x] [(str "/" x) (list x 'request)]) addresses)
"/" (home ~'request)
(status-response 404 (str "<h1>404 Not Found: " (:uri ~'request) "</h1>" )))))
答案 1 :(得分:1)
宏代码的问题在于,作为quasiquoting一部分的动态符号不能在引用部分之外使用,即在unquote / unquote-splicing代码中。但是另一种方式是可能的,那就是你在宏执行部分做gensym并在quasiquoting部分中使用它,如下所示:
(defmacro def-handler [& addresses]
(let [request (gensym)]
`(defn handler [~request]
(case (~request :uri)
~@(mapcat (ƒ [x] [(str "/" x) (list x request)]) addresses)
"/" (home ~request)
(status-response 404 (str "<h1>404 Not Found: " (:uri ~request) "</h1>"))))))