首页 文章

使用leiningen评估clojure文件的时间和次数是多少?

提问于
浏览
3

我发现在编写代码时添加了警告,这些代码编写了一个文件正文在编译期间执行两次的宏 . 是否有一个原因?这是leiningen特有的吗?我不能用 (compile ...) 重现这个 .

简化版:

(ns foo.core
    (:require foo.bar))

;; empty

(ns foo.bar)

(println "hello")

$ lein compile:all编译foo.core你好编译foo.bar你好

进一步测试表明在编译期间命名空间在其自身上重新加载:

(ns foo.bar)

(declare wasd)
(println wasd)
(def wasd 2)

$ lein clean $ lein compile:all编译foo.core#<Unbound Unbound:#'foo.bar / wasd>编译foo.bar 2

在一个更复杂的情况下,我在编译期间发生这种情况,然后每次运行或从lein开始一次repl . 我不知道为什么 . 这完全是clojure 1.6和leiningen 2.5.0 .

2 回答

  • 5

    Leiningen在名称空间如何与彼此相关方面对项目的结构一无所知 . 因此,在编译项目时, lein 只是引导JVM并强制每个名称空间一次加载一个 . 这意味着,正如您所注意到的,将重新加载名称空间,从而导致您注意到的双重评估行为 .

    相比之下,(clojure.core/compile)只是使用clojure.core/compile-files bound加载目标资源 . 这将导致目标资源及其所需的所有资源被加载并编译为类文件 . 但是,它不会遍历整个项目结构,因为Leiningen的编译操作会编译所有资源 .

  • 1

    您在编译期间看到 println 输出的原因是因为在命名空间评估期间调用 println . 你的程序应该有 -main fn或其他一些调用 println 的入口点 .

    (defn -main [& _]
      (println "Won't see on compile.")
      (println "lein run -- is printing from -main"))
    

    我认为您的项目正在抛出一个未绑定的异常,因为您在为其分配值之前尝试使用 println 引用 wasd 变量 . 声明了变量,但在 println fn尝试获取值之前没有为其分配任何内容 .

相关问题