0

我有这个功能:

(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>" ))))

但我一直在更改页面列表-which-resolve-to-functions-with-the-same-name,我希望能够写:

(def-handler 善恶中立)

反而:

但我被困住了。到目前为止,我最好的镜头如下:

(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>" )))))
4

2 回答 2

3

我认为您完全可以避免使用 gensym 。我看不出不使用 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>" )))))
于 2013-01-31T13:18:38.000 回答
1

您的宏代码的问题在于,作为准引用一部分的动态符号不能在引用部分之外使用,即在取消引用/取消引用拼接代码中。但是另一种方法是可能的,即您在宏执行部分执行 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>")))))) 
于 2013-02-02T16:37:05.123 回答