2016-01-12 45 views
2

我創建了一個API服務器的庫,這裏有我一個simpliefied版本有:一個在宏綁定沒有解決

(defonce ^:dynamic *my-token* nil) 

(defmacro def-my-token 
    [token1 & body] 
    `(binding [*my-token* ~token1] [email protected])) 

和主「後」的方法:

(defn my-post-request [url1] 
    (try 
    (let [res (client/post (str "api/url/base" url1) 
       {:body (json/write-str (:secret my-token)) ; my-token should come from the macro 
     ;...... 

這裏就是我想用它:

(defn -main [& args] 
    (def-my-token "fdsfdsfdsfds" 

    ; now "my-token" should be created and visible in "my-post-request", shouldn't it? 
    (print 
    (my-post-request "/some_end_point")))) 

但它說:「無法解析符號:我的令牌在這種情況下」

我想知道爲什麼? doens't def-my-token,是一個宏,定義它?爲什麼不?以及如何解決這個問題?

更新: 也沒有(defonce ^:dynamic *token* nil)它不起作用。爲什麼不? 爲什麼不定義宏不夠?

+3

'defonce'和^:動態有點不一致。試試'def'代替。 – jmargolisvt

回答

3

you bound *my-token*,not my-token。嘗試:

{:body (json/write-str (:secret *my-token*)) 

星號只是動態變量的命名約定,它們仍然是實際變量名稱的一部分。

+0

謝謝,我已經更新了我的問題。 –

3

回答您的UPDATE:

據爲binding的文檔,你只能覆蓋已有瓦爾。這就是爲什麼您的解決方案無法與動態變量建立根綁定的原因。

旁註:

我會建議做jmargolisvt說,用普通def代替defonce,因爲我從來沒有見過使用defonce在野外任何動態無功的定義。

編輯:

好好嘗試一下DEF-我的令牌,作爲一個宏定義的呢?爲什麼不?以及如何解決這個問題?

宏本身並沒有定義的東西,它們是在大多數Lisp REPL的宏擴展步驟中轉換源代碼的小程序。它可以定義任何你想要的,但是你應該寫下def特殊形式。你用的是binding,它處理已經存在的變量。 您可以通過在REPL中玩弄它和/或閱讀stackoverflow answer的答案來獲得更多的洞察。

如果您需要一些進一步的解釋,爲什麼需要overriding: 將變量概念化爲堆棧是實用的。您使用def建立的根綁定是第一層。除非您將「某物」置於其上,否則程序中的所有內容都將看到此值。正如你可以想象你的例子中*my-token*被看作nil從你的函數會導致問題。

binding來拯救!

它可以讓你把任何東西「上面」根結合的(在你的情況nil)線程局部身體它的內部,像這樣:

vars

+0

它與重寫有什麼關係?爲什麼我首先需要它? –

相關問題