问题描述:

I've got this function:

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

but I keep changing the list of pages-which-resolve-to-functions-with-the-same-name and I'd like to be able to write:

(def-handler good evil neutral)

instead:

But I am stuck. My best shot so far looks like:

(defmacro def-handler [& addresses]

`(defn handler [request#]

(case (request# :uri)

[email protected](mapcat (fn[x] [(str "/" x) (list x 'request)]) addresses)

"/" (home request#)

(status-response 404 (str "<h1>404 Not Found: " (:uri request#) "</h1>" )))))

But it does not quite work because the request in the generated calls is not the gensym, and I am at a loss how to get the gensym in there.

This looked promising until I noticed it made a new gensym:

(defmacro def-handler [& addresses]

`(defn handler [request#]

(case (request# :uri)

[email protected](mapcat (fn[x] [(str "/" x) `( ~x request#)]) addresses)

"/" (home request#)

(status-response 404 (str "<h1>404 Not Found: " (:uri request#) "</h1>" )))))

网友答案:

I think you can avoid gensym here at all. I don't see how you can "pollute" environment by not using gensym. Example without gensym:

(defmacro def-handler [& addresses]
  `(defn handler [~'request]
     (case (~'request :uri)
       [email protected](mapcat (fn[x] [(str "/" x) (list x 'request)]) addresses)
       "/" (home ~'request)
       (status-response 404 (str "<h1>404 Not Found: " (:uri ~'request) "</h1>" )))))
网友答案:

The problem with your macro code is that the dynamic symbol which is part of quasiquoting can't be use outside quoted part i.e in the unquote/unquote-splicing code. However the other way is possible, that is you do gensym in the macro execution part and use that inside quasiquoting part as shown below:

(defmacro def-handler [& addresses]                                                                                                                  
  (let [request (gensym)]                                                                                                                            
  `(defn handler [~request]                                                                                                                          
     (case (~request :uri)                                                                                                                           
       [email protected](mapcat (ƒ [x] [(str "/" x) (list x request)]) addresses)                                                                                   
       "/" (home ~request)                                                                                                                           
       (status-response 404 (str "<h1>404 Not Found: " (:uri ~request) "</h1>")))))) 
相关阅读:
Top