2011-11-04 32 views
2

下面定義的宏,transform!似乎適用於=> (transform! ["foo" 1 2 3])。目的是獲取一個列表,第一個元素是一個表示名稱空間中的函數的字符串。然後把所有東西都包裝成swap!使用交換內的字符串調用Clojure函數?

問題是transform!不適用於=> (transform! coll),其中(def coll ["foo" 1 2 3])。我得到這個神祕異常:

#<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: Symbol> 

功能:

(defmacro transform! 
" Takes string input and update data with corresponding command function. 
" 
    [[f & args]] ;; note double brackets 
`(swap! *image* ~(ns-resolve *ns* (symbol f)) [email protected])) 

我覺得奇怪的是它爲一個案件,而不是其他。

回答

5

宏在編譯時工作,並在代碼上運行,而不是在運行時數據上運行。在(transform! coll)的情況下,該宏正在被傳遞一個未經評估的參數:符號coll

你實際上並不需要宏;常規功能就足夠了:

(defn transform! [[f & args]] 
    (apply swap! *image* (resolve (symbol f)) args))) 

解決瓦爾在運行時可能會被認爲是一個代碼味道,所以想想你是否真的需要做到這一點。

0

您正在向宏傳遞一個符號,即coll。它會嘗試根據解構陳述[f & args]將這個符號分開,當然這是不可能的。

您也可以使用(resolve符號)代替(ns-resolve * ns *符號)。