2011-03-28 18 views
6

compojure library in the core namespace,我看到以下形式:clojure:#'/(var ...)表單有什麼用?

(defn- compile-route 
    "Compile a route in the form (method path & body) into a function." 
    [method route bindings body] 
    `(#'if-method ~method 
    (#'if-route ~(prepare-route route) 
     (fn [request#] 
     (let-request [~bindings request#] 
      (render (do [email protected]) request#)))))) 

(defmacro GET "Generate a GET route." 
    [path args & body] 
    (compile-route :get path args body)) 

此外向上在文件中,所述if-methodif-route功能與defn-已定義。

雖然我不明白#'在這個compile-route函數中的含義。 (var ...)的文檔說:

該符號必須解析爲var,並返回Var對象本身(不是它的值)。讀者宏#'x擴展爲(var x)。

但是對於我而言,在發生什麼(即從defmacro調用)的情況下,它聽起來像是意味着符號的值將被返回,這與可替代性聽起來的相同:

(def x 5) 
(+ x 7) 
-> 12 

(+ x 7)擴展,或者是一樣的,(+ 5 7)

缺少什麼我在這裏?

回答

4

在此尋找了一段時間後,我開始懷疑它有話與事實if-methodif-route功能實際上是私人的((defn- if-route ...))。

另外,宏,當你做回剔引號(「`」),你實際上得到的最終膨脹完全命名空間指定符號:

`(+ 2 3) 

將擴大到

(clojure.core/+ 2 3) 

由於這些方法是私有的,所以它們在普通擴展中將不可訪問,因此使用var函數來獲取引用實際函數的符號,該函數必須在此處調用擴張。

+1

這正是原因。 – kotarak 2011-03-30 07:21:24

+0

感謝您的確認! – 2011-03-31 13:20:51

+0

還有一點評論:符號不包含參考。瓦爾做。這對於IIUC的Lisp是個區別。符號只是名稱,由編譯器解析爲Vars。代碼有效,因爲Var將所有的'.invoke'調用委託給它所持有的東西。 – kotarak 2011-03-31 14:36:42

3

ring-reload可以從開發過程中不斷修改的文件重新加載var定義。既然你傳遞了一個(var ...),那麼每當你嘗試讀取它時都會被解析,因此重載的變量可以在每次請求時重新讀取。這導致了交互式Web開發(不需要編譯等)。如果你不使用(var ...),而是直接傳遞值,那麼重新加載的變量不會傳遞給環形URI處理程序,因此你不能修改並運行你的代碼。

入住此博客條目,例如:

http://charsequence.blogspot.com/2010/09/interactive-web-development-with.html