这听起来像一个设计监督与语法引用(在我看来),虽然不清楚一般的“修复”是什么样子。
这里是一个更小例子:
yummly.mobile-api.main> (in-ns 'foo)
#namespace[foo]
foo> (clojure.core/refer-clojure)
foo> (require '[org.httpkit.client :as client])
nil
foo> (defmacro xxz [& fns]
`([email protected]))
#'foo/xxz
foo> (macroexpand-1 '(xxz client/get))
(client/get)
从一个新的命名空间:
foo> (in-ns 'bar)
#namespace[bar]
bar> (macroexpand-1 '(foo/xxz client/get))
(client/get)
bar> (foo/xxz client/get)
CompilerException java.lang.RuntimeException: No such namespace: client, compiling:(*cider-repl api*:87:6)
语法引号形式(又名`)着眼于表达每一个符号,因为它是被编译,如果它没有找到一个/然后它假定它是为本地命名空间并追加当前命名空间。它只能在宏定义时出现在实际宏中的符号,而不是(因为我希望它能够做到)符号作为参数传递给宏。
如果您在宏中使用完全名称空间限定符号,那么如果名称空间中用户使用宏的名称空间已将这些符号映射到任何内容,则无需担心,因为它们会拼出符号名称的完整路径。如果您不想在宏中使用的符号中输入完整名称空间,则可以在ns
表达式中的require语句中使用:refer [get]
,这样可以节省您输入名称并使其成为正确的命名空间在宏定义评估时展开。
因为语法报价是生产unhygenic符号,则需要两个都:需要或:指功能在ns
部分在命名空间的顶部,在那里这些命名空间传递给函数的每一位客户。
另一种方法是找到一些方法来确保符号在编译语法引用时可用于宏。在某些情况下,这可能会很棘手。
不知道我明白。如果你在ns“sample”中并且调用了(xxz ...),那么ns“sample”必须有'(:require [some-ns.client:as client])或类似的名称。 –