Hi everyone, is there a way to tell lein which order to load the files in? especially in the case that the load order cannot be determined by name space requirements?
The only way I can think of doing it is to create empty name spaces, one per file which needs to be loaded. And then :require
those name spaces in the order which I know they need to be loaded. This seems to work, but sounds like a hack.
@jimka.issy what do you mean by “load files in”?
as in compile them?
like via :aot
option?
@mikerod, if you have several files in the directory, it seems the project.clj file indicates in the defproject which is the first file to load via the :main keyword. And thereafter if any file defines a ns which requires other packages to be loaded, they seem to be loaded by assuming the name of the file matches the ns name.
what about other files which don't match the ns name?
how am I supposed to force them to be loaded?
as per the compilation, as I understand it load semantics and are the same whether loading from source and compiling on the fly, or loading from pre-compiled files. right?
an example would be a file which does not begin with (ns ...)
but rather begins with (in-ns ...)
The problem is that lein assumes ns name is derivable from file name. This is an unfortunate assumption which was not intended by clojure's design, otherwise in-ns
would not exist. In my opinion this is a bug in lein, in that it is requiring the user to provide redunant information.
bug is a strong work. I understand the heritage comes from java, so we're not starting from a perfect world by any means.
I don't think there is actually a requirement in Leiningen for every source file to start with an ns
form with a name that corresponds to the file name. Clojure require
given a namespace name will always look for it in a file with a corresponding file name, but I doubt Leiningen imposes any more requirements than that.
Here is a tiny demo Leiningen project demonstrating that one can have files that contain no ns
form at the beginning, that can be loaded via a call to load
from a different source file in the same project: https://github.com/jafingerhut/loaddemo
I have heard Stuart Halloway make a comment noting that while require
has this namespace<->filename correspondence built into it, you can concatenate the contents of most (all?) multi-file Clojure projects in a valid order where things are defined before they are used, and just concatenate those all into one big file, or copy and paste that all into a REPL session, and the issue of file names, and even of files in the file system, never arises, and things can work that way.
Most people don't create Clojure code bases that way, of course.
I suspect that the creation of in-ns
was motivated more by live REPL development, and the desire to switch from one namespace to another in a live REPL session, more than anything else.
Can someone help me find the documentation for defproject
?
i.e., what are all the possible options and their meanings?
One source is a huge sample project.clj file included with Leiningen that has many comments. Not necessarily full documentation, but at least mentions most possible things: https://gitlab.com/technomancy/leiningen/blob/master/sample.project.clj
As in, the file beginning with (in-ns ...)
is code that belongs in a namespace whose (ns ..)
form is in another file?
If yes, then I have seen such files loaded from the file containing the (ns ...)
form in clojure.core's namespace, like this:
(load "core_proxy")
(load "core_print")
(load "genclass")
(load "core_deftype")
(load "core/protocols")
(load "gvec")
what's the path name relative to?
re your question above. yes. several files which contribute to the same ns.
The way I've figured out how to do it is just define a bunch of empty name spaces, one per file, And the top of the files look like the following
(ns clojure-rte.type-extend
"This is an empty namespace to fool lein to load this file as part of
the clojure-rte.core ns.")
(in-ns 'clojure-rte.core)
I wonder whether it is better to call load
directly. My guess is that calling load
directly will confuse lein when trying to print error messages if a problem happens at load time. Just my but feel though.
lein sample
If you want to avoid the question, you can simply put all code that you want to belong in one namespace in one file, with a name corresponding to the namespace name. The upper limit on the size of one is quite large (not sure what exactly determines it).
Using load
like used in the clojure.core
namespace you can split the contents of a single namespace across multiple files.
The load
calls in any namespace foo.bar
should execute whenever ns foo.bar
is require'd, or loaded in any way, I believe.
I would expect it would be confusing to many readers of code to have an ns
form at the beginning of a file, which corresponded to the file name, but then soon afterwards have (in-ns ..)
` with a different namespace name, and none of the code was actually in the namespace named in the ns
form. Obviously Clojure allows you to do this -- just saying it would look odd to me.