2013-04-02 54 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