Author: masnun
Scripting Clojure
Clojure Startup time is not ideal for day to day scripting with it. But in case you do want to run Clojure scripts, it is possible.
We need to use the “lein exec” plugin to leiningen. Edit ~/.lein/profiles.clj and add these codes:
1 |
{:user {:plugins [[lein-exec "0.3.4"]]}} |
Now the next time you run any leiningen commands, it would install the plugin. You can now execute single file clojure programs by:
1 |
lein exec main.clj |
For more convenience, I added this to my .zshrc:
1 |
alias clojure="lein exec" |
Now I can do this:
1 2 |
$ clojure main.clj Hello World |
You can also use “lein exec” for shebang, like this:
1 2 3 |
#!/usr/bin/env lein exec (println "Hello World") |
Make the file executable and run it like:
1 2 |
$ chmod a+x main.clj $ ./main.clj |
I have started playing with Clojure lately and I found the Clojure start up time quite slow. Every time I make a change and re-run using:
1 |
lein run |
I have to wait quite a bit of time.
For quick prototyping, a better approach is to run the repl using:
1 |
lein repl |
We run our main function from the repl using (-main). when we make changes – we reload our code and then run the “-main” function again. To follow this approach, we have to make sure that we added [org.clojure/tools.namespace “0.2.7”] to our leiningen dependencies list (add this to the project.clj file inside your project). Then launch the REPL and type these code:
The (refresh) call would reload the changed namespaces and (-main) would run the main function again.
So that works but every time we open the REPL, we have to type the require command in. One of the awesome features of Leiningen is it allows us to load source codes from additional paths based on profiles. We would add a dev profile and load some codes from a different path. These codes will be loaded by leiningen while running the app but won’t be a part of our JAR file.
To add a dev profile, let’s update the “project.clj”:
Now in our project root, if we create a file “startup/user.clj”, Leiningen would load this file on startup.
So we add these code to the “startup/user.clj” file:
Note that the refresh function takes an “:after” option. If we pass a fully qualified function name, it will call that function after reloading the namespace.
Now any time we make changes to our files, we can just call (user/rerun) and it would reload the libraries and execute the “-main” function.