这类似于将 Clojure 宏视为函数中讨论的问题,但是在尝试最佳答案中的方法时,我得到了一个错误。希望关于我的特定应用程序的太多信息是不必要的,因为它非常复杂,但这里是我尝试做的一个精简版本:
(defmacro make-fn [m arg1]
`(fn [& args#]
(eval `(~'~m ~'~arg1 ~@args#))))
我在这种情况下使用了宏:
(let [columns (make-columns table-width)
table-name (keyword (str "table_" n))]
(apply (make-fn helpers/tbl table-name) columns))
“helpers/tbl”是一个宏,它需要一个表名关键字和可变数量的包含列规范的列表(如 [:varchar 100] 或其他东西)。我正在尝试动态创建随机数据库表规范以方便一些测试。无论如何,在尝试执行上述代码时,我收到以下错误:
CompilerException java.lang.RuntimeException: Unable to resolve symbol: table-name in this context, compiling:(NO_SOURCE_PATH:1)
我有点理解这个问题:宏扩展是在编译时完成的,我试图在宏扩展中包含一个运行时值,因此奇怪地使用引用和取消引用来让一切设置得恰到好处。我基本上想要一个宏的部分,并且我需要能够为不同命名空间中的不同宏重用这种机制,并让所有变量解析正确。这甚至可能吗?