我在一个ns中定义了以下内容 -
有一个服务原子,另一个要添加到该原子的函数 -
(ns ex.first)
(def services (atom []))
(defn add-service
[fns]
(swap! services conj fns))
在另一个ns的代码中,我这样做 -
(ns ex.second ..)
(add-service [fn1 fn2 fn3])
1)我假设当我运行编译代码的repl时,它应该将向量添加到原子中。但是当我评估@services
时,它会返回[]
。
2)如果我在repl中评估(add-service [fn1 fn2 fn3])
,则上述情况有效。
3)我也尝试过将add-service
fn转换为宏。但是我发现@services
仍然是空的。
如果有人能帮助解决这些问题,我们将不胜感激。
1)为什么在 -
时,add-service调用不会在代码编译时向atom添加向量add-service
被定义为fn
。 add-service
被定义为macro
。2)我如何使它工作:)
答案 0 :(得分:4)
这取决于您是否在project.clj中将:aot
设置为:all
。
如果:aot
为:all
,则只要启动repl就会执行函数调用,否则您需要加载ex.second
命名空间(例如:使用use
)。加载将导致ns被编译,相应的类将被加载到jvm中,函数调用将被执行。
此外,函数调用不会在编译时发生,它发生在jvm加载编译的类(表示命名空间)时。
更新(根据评论):
如果你把它变成一个宏,那么你也需要考虑一下它。
如果aot设置为编译命名空间,则lein将创建一个jvm,在其中加载代码,调用clojure编译器,这将读取代码,执行宏并编译代码,此时这个jvm(这是用于编译你的代码)将有services
原子填充的宏执行,但这个jvm只用于编译。然后lein将为run命令创建另一个jvm并在该jvm中加载已编译的类,但是这个jvm将不会填充services
因为类没有任何填充它的代码。
如果未设置aot,那么宏将起作用,因为read,macroexpand,编译过程将在lein run jvm中发生,但仅在你加载ns时才会发生。
就“不加载ns”而言,您可以做的是将ex.second
放在project.clj的:aot
中