We assume that the development environment is either Linux or macos.
lein
as an executable script, and it will automatically install the
necessary Clojure compiler and libraries.$ lein new hello-world
Generating a project called hello-world based on the 'default' template.
The default template is intended for library projects, not applications.
To see other templates (app, plugin, etc), try `lein help new`.
The empty project has a function declared foo
which we can choose to run:
$ lein run -m hello-world.core/foo Blah
Blah Hello, World!
Suppose we inject a run-time error into foo
:
(defn foo [x]
(println (* x 2) ": hello world"))
This leads to a run-time error, and with a rather unreadable stack trace.
$ lein run -m hello-world.core/foo Blah
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot
be cast to java.lang.Number,
compiling:(/tmp/form-init1872070180712311231.clj:1:73)
at clojure.lang.Compiler.load(Compiler.java:7391)
at clojure.lang.Compiler.loadFile(Compiler.java:7317)
at clojure.main$load_script.invokeStatic(main.clj:275)
at clojure.main$init_opt.invokeStatic(main.clj:277)
at clojure.main$init_opt.invoke(main.clj:277)
at clojure.main$initialize.invokeStatic(main.clj:308)
at clojure.main$null_opt.invokeStatic(main.clj:342)
at clojure.main$null_opt.invoke(main.clj:339)
at clojure.main$main.invokeStatic(main.clj:421)
at clojure.main$main.doInvoke(main.clj:384)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to
java.lang.Number
at clojure.lang.Numbers.multiply(Numbers.java:148)
at clojure.lang.Numbers.multiply(Numbers.java:3740)
at hello_world.core$foo.invokeStatic(core.clj:6)
at hello_world.core$foo.invoke(core.clj:3)
at clojure.lang.Var.invoke(Var.java:379)
at user$eval2820.invokeStatic(form-init1872070180712311231.clj:1)
at user$eval2820.invoke(form-init1872070180712311231.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.eval(Compiler.java:6917)
at clojure.lang.Compiler.load(Compiler.java:7379)
... 14 more
The reason that the stack trace so unreadable is because it is generated by the Java VM.
project.clj
Leiningen uses Clojure data structure to configure the project.
We will add a really cool stack trace formatter.
(defproject hello-world "0.1.0-SNAPSHOT"
:plugins [[io.aviso/pretty "0.1.34"]]
:dependencies [[org.clojure/clojure "1.8.0"]
[io.aviso/pretty "0.1.34"]])
Let’s run the erroneous foo
function.
$ lein run -m hello-world.core/foo Blah
1 ↵
Uncaught exception in thread main:
clojure.main.main main.java: 37
...
clojure.main/main main.clj: 384
clojure.main/main main.clj: 421
clojure.main/null-opt main.clj: 342
clojure.main/initialize main.clj: 308
clojure.main/init-opt main.clj: 277
clojure.main/load-script main.clj: 275
...
user/eval3108 REPL Input
...
hello-world.core/foo core.clj: 6
...
java.lang.ClassCastException: java.lang.String cannot be cast to
java.lang.Number
clojure.lang.Compiler$CompilerException: java.lang.ClassCastException:
java.lang.String cannot be cast to java.lang.Number,
compiling:(/tmp/form-init3260028141421924083.clj:1:73)