【发布时间】:2013-02-27 18:19:00
【问题描述】:
我有一个宏生成宏,我试图从另一个命名空间调用它,但它失败并显示“无法引用不存在的合格变量”。
我设法在下面的代码中重现了它,这是最简单的例子,可以说明问题。我也找到了解决方法,但是我想了解问题的原因以及是否存在更好的解决方案。
问题
文件 foo.clj
(ns foo)
(defmacro create-my-macro []
`(defmacro my-macro []
nil))
文件 boo.clj
(ns boo (:use [foo]))
(create-my-macro)
上面的代码执行时:
java -cp clojure-1.4.0.jar clojure.main boo.clj
... 失败:
Exception in thread "main" java.lang.RuntimeException: Can't refer to qualified var that doesn't exist, compiling:(...boo.clj:2)
解决方法
由于某种原因,当宏生成宏被增强以接受要创建的宏的名称作为参数时,没有失败。
文件 foo.clj
(ns foo)
(defmacro create-my-macro [macroName]
(let [the-macroName (symbol macroName)]
`(defmacro ~the-macroName []
1)))
文件 boo.clj
(ns boo (:use [foo]))
(create-my-macro "foo")
(println (foo))
如上运行文件 boo.clj 在控制台上输出一个干净的“1”,没有任何抱怨。
那么,在第一种情况下出了什么问题,是否有另一种方法可以解决它,更改宏生成宏以接受要生成的宏的名称作为参数?另外,同一个命名空间调用macro-generating-macro时为什么不失败?
【问题讨论】: