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
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
Normally you’ll want to use the same method that you use with library code, which is to
use/requireyour namespaces (through annsform at the top of the file and sometimes theuse/requirefunctions 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 filesrc/foo/bar/baz.cljdefines a namespace calledfoo.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.barnamespace needs to use code from thefoo.quux.baznamespace, do something like(ns foo.bar (:require [foo.quux.baz :as baz]))infoo/bar.cljand call functions frombazasbaz/some-function. Or you can put(:use foo.quux.baz)in thensform 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 yourjars to the classpath in some scenarios, e.g. if you plan on callingcompileto produce.classfiles, 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-nsto 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.