Simple question. I'm new to Clojure.
How can I use one file from my project in another file? Basically how can I include, import, or require another file? Not from libraries but fro my own code.
Thanks, Alex
Simple question. I'm new to Clojure.
How can I use one file from my project in another file? Basically how can I include, import, or require another file? Not from libraries but fro my own code.
Thanks, Alex
Normally you'll want to use the same method that you use with library code, which is to use
/ require
your namespaces (through an ns
form at the top of the file and sometimes the use
/ require
functions at the REPL). For this to work, you have to make sure they are on the classpath. A short guide to that:
Follow the usual Clojure project structure: a src/
directory containing all your source files, where file src/foo/bar/baz.clj
defines a namespace called foo.bar.baz
. Note that you must maintain the directory structure / namespace name structure correspondence; things won't work otherwise. Also note that you must not use the _
character in namespace names or the -
character (the hyphen) in filenames and whenever you use _
in filenames you must use a -
in namespace names (and the other way around.) Finally, the directory hierarchy will be slightly more complicated with Maven projects, but don't worry about this for now (unless you're already a proficient user of Maven, in which case this won't be a problem for you).
Also see this answer of mine to an earlier SO question about Java classpath handling with Clojure for a more detailed step-by-step explanation of the filesystem hierarchy / classpath hierarchy correspondence.
If your code from the foo.bar
namespace needs to use code from the foo.quux.baz
namespace, do something like (ns foo.bar (:require [foo.quux.baz :as baz]))
in foo/bar.clj
and call functions from baz
as baz/some-function
. Or you can put (:use foo.quux.baz)
in the ns
form instead to call them directly (without the namespace qualifier, e.g. some-function
). That's exactly the same thing as what you'd do for library code.
When working with your project's code from the REPL, make sure you include the src/
directory (the directory itself, not any of the files therein) on the classpath. You should probably consider using some tool to automate the REPL setup (including classpath management) for you; Leiningen is very popular with Clojurians and there are plugins for using Maven with Clojure too.
Warning: Your JVM-launching command might (in fact, probably will) recognise an environment variable called $CLASSPATH
. As for its relationship to your Clojure projects, well, basically there should be none. More likely than not, your projects will require a different classpath each, with some possibly using versions of certain jars incompatible with those required by others (notably if you're using Clojure 1.1 -- latest stable release -- for some projects, while experimenting with 1.2 snapshots with others). Thus the correct way of managing the classpath is to prepare a minimal version for each project and pass that to the JVM launching command. As mentioned previously, you should invest some time in learning to use a good tool (like the above mentioned Leiningen) to set up the classpath for you as soon as possible so you don't need to care about this yourself.
(As a side note, you might have to add more than just the src/
directory and your jar
s to the classpath in some scenarios, e.g. if you plan on calling compile
to produce .class
files, you'll have to put the target directory on the classpath too. That's beyond the scope of this question, though.)
BTW, I've started this answer with the word "normally", because you could also use things like load
& in-ns
to split a single namespace into multiple files. Most of the time this won't be what you really want to do, though; just use a well thought out namespace layout instead.