2013-04-02 28 views
3

我有一个产生函数的宏。我知道最好的做法是使用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。我原本想知道是否有必要。无论如何,感谢阅读。

回答

2

在这种情况下,使用req是相对安全的,因为它建立了一个本地范围。作为一个函数参数,它会将任何现有的绑定映射到调用名称空间中的符号req而不会损坏它们。这样做的代价是,如果有人试图使用名称req作为其他任何参数(如处理程序),他们可能会有点意外。在我看来,这段代码没有错,尽管它在某些情况下最少提供的原则是。考虑到这只是添加几个# s的工作,我没有看到任何理由不要使用req的自动gensym。

+0

太好了,谢谢你的解释!你是对的:追加'#'当然没有额外的努力。 – maxcountryman