Reputation: 13604
Suppose you have the following code:
(ns foo)
(defmacro defproject [project-name version & args]
...
)
(defn read-project ([file]
(load-file file)))
Update: The full code can be found at https://github.com/derkork/intellij-leiningen-plugin/blob/master/src/de/janthomae/leiningenplugin/leiningen/LeiningenProjectFile.clj
Now i call read-project on a file "project.clj" that has the following contents:
(defproject de.janthomae/leiningenplugin "1.0.0-SNAPSHOT"
...
)
And I get the following error message
java.lang.Exception: Unable to resolve symbol: defproject in this context (project.clj:1)
at clojure.lang.Compiler.analyze(Compiler.java:4420)
at clojure.lang.Compiler.analyze(Compiler.java:4366)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:2828)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:4594)
at clojure.lang.Compiler.analyze(Compiler.java:4405)
at clojure.lang.Compiler.analyze(Compiler.java:4366)
That tells me it doesn't find my defproject macro. And I am totally clueless why it is that way, since the macro is defined just a few lines ahead. Do I need to export it somehow so it can be seen from files which are loaded using load-file?
Upvotes: 4
Views: 453
Reputation: 3408
project.clj doesn't indeed know where to look for foo/defproject. So if you are on repl, you can do
user> (in-ns 'foo)
foo> (read-project "project.clj")
This will run code from project.clj inside foo namespace, where defproject is defined. Or you can place (in-ns 'foo) inside project.clj. Result will be the same.
But you can also write something like this in project.clj:
(foo/defproject ...)
This will call defproject inside your current namespace when you run (foo/read-project "project.clj").
from test_uberjar.clj:
(def project (binding [*ns* (the-ns 'leiningen.core)]
(read-project "test_projects/sample_no_aot/project.clj")))
from test_deps.clj:
(:use [leiningen.core :only [read-project defproject]] ...)
So, defproject is always available when doing load-file.
Upvotes: 1