When and how many times can a clojure file be evaluated with leiningen?

I discovered by adding warnings to the code that writes macros that the file body is executed twice at compile time. Is there a reason for this? Is this leiningen specific? I cannot reproduce this with (compile ...)

.

Simplified version:

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

;; empty

      


(ns foo.bar)

(println "hello")

      

$ lein compile: all

Compiling foo.core

hello

Compiling foo.bar

hello

Further testing shows that the namespace is reloaded over itself at compile time:

(ns foo.bar)

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

      

$ lein clean

$ lein compile: all

Compiling foo.core

#<Unbound Unbound: #'foo.bar/wasd>

Compiling foo.bar

2

In a more complex case, this happens at compile time and then once each time you run or run repl from lein. I do not know why. All this with clojure 1.6 and leiningen 2.5.0.

+3


source to share


2 answers


Leiningen knows nothing about the structure of your project in terms of how namespaces relate to each other. Hence, when the project is compiled, it lein

just loads the JVM and forces each namespace to load one at a time. This means that, as you noticed, the namespaces will be reloaded, which will replace the double evaluation.



For comparison, it (clojure.core/compile)

just loads the target resource with clojure.core/*compile-files*

. This will cause the target resource and all the resources it needs to be loaded and compiled into class files. However, it will not move the entire project structure by compiling all the resources like the Leiningen compile operation does.

+5


source


The reason you see the output println

at compile time is because the namespace is called during evaluation println

. You must have -main

fn or some other entry point for your program to call println

.

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

      



I think your project is throwing an Unbound Exception because you are trying to reference a variable wasd

with println

before it has been assigned a value. This variable has been declared, but nothing has been assigned to it before println

fn tries to get a value.

+1


source







All Articles