我有一个生成函数的宏。我知道最好的做法是使用gensyms来确保不会发生命名冲突。所以我想知道我是否需要遵循宏将定义的函数的参数名称的这个原则?
这是我的宏观供参考:
(defmacro defroute
[routename uri meths handler]
`(defn ~routename
[~'req]
(let [req-meth# (:request-method ~'req)
bad-meth# (nil? (some #(= req-meth# %) ~meths))
any-meth# (= ~meths [:any])]
(if (:uri ~'req)
(if (and (route-matches ~uri ~'req) (and bad-meth# (not any-meth#)))
(method-not-allowed req-meth# (get-allowed ~meths))
(let [params# (route-matches ~uri ~'req)]
(if (nil? params#)
~'req
(~handler (assoc ~'req :route-params params#)))))
~'req))))
如您所见,我目前没有使用req
参数的gensym。我原来然后想知道是否有必要。无论如何,感谢阅读。
答案 0 :(得分:2)
在此上下文中,req
的使用相对安全,因为它建立了本地范围。作为函数参数,它将遮蔽调用命名空间中符号req的任何现有绑定,而不会损坏它们。这样做的代价是,如果有人试图将名称req用于任何其他参数,例如处理程序,那么他们可能会有点意外。在我看来,这段代码并没有错,尽管在某些情况下它确实表达了最低限度原则。我认为没有任何理由不使用req
的自动gensym,只考虑添加一对#
的工作。