在swap中使用字符串调用Clojure函数?

时间:2011-11-04 17:09:25

标签: macros clojure

下面定义的宏transform!似乎适用于=> (transform! ["foo" 1 2 3])。目的是获取一个列表,第一个元素是表示命名空间中的函数的字符串。然后将所有内容包装到swap!

问题是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)) ~@args))

我觉得奇怪的是它适用于一个案例而不是另一个案例。

2 个答案:

答案 0 :(得分:5)

宏在编译时工作并对代码进行操作,而不是对运行时数据进行操作。在(transform! coll)的情况下,宏被传递一个未经评估的参数:符号coll

你实际上并不需要一个宏;常规功能就足够了:

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

在运行时解析vars可能会被视为代码气味,所以请考虑一下你是否真的需要这样做。

答案 1 :(得分:0)

您将符号传递给宏,即coll。它将尝试根据解构声明[f&amp; args],当然不可能。

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