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

时间:2014-11-21 04:18:23

标签: clojure compilation leiningen

我发现在向编写宏的过程中添加警告时,文件正文在编译过程中被执行了两次。是否有一个原因?这是leiningen特有的吗?我无法使用(compile ...)重现此内容。

简化版:

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

;; empty

(ns foo.bar)

(println "hello")
  

$ lein compile:all

     

编译foo.core

     

hello

     

编译foo.bar

     

hello

进一步的测试表明,在编译期间,命名空间会自行重新加载:

(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 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:1)

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

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

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