Clojure provides command line tools for:
In all the above scenarios you might want to use other Clojure and Java libraries. These may be libraries you are writing locally, projects in git or libraries available in the Maven ecosystem and hosted by central repositories like Maven Central or Clojars.
Using a library involves:
Clojure tools specify a syntax and file (deps.edn
) for (a), given which
they’ll handle (b) and (c) automatically.
Start a ‘REPL’ by running the clj
tool:
$ clj Clojure 1.10.1 user=>
Once in the ‘REPL’ you can type Clojure expressions and press enter to evaluate them. Type ‘Control-D’ to exit the ‘REPL’:
There are many Clojure and Java libraries available that provide access to
practically any functionality you might need. For example, consider the
commonly used Clojure library clojure.java-time
for working with dates and
times.
To work with this library, you need to declare it as a dependency so the tool can ensure it has been downloaded and add it to the classpath. The readme in most projects shows the name and version to use.
deps.edn
file to declare the dependency
clj
tool
deps.edn
file
and explore Clojure or Java libraries.
{:deps {clojure.java-time/clojure.java-time {:mvn/version "0.3.2"}}}
$ clj Downloading: clojure/java-time/clojure.java-time/0.3.2/clojure.java-time-0.3.2.pom from clojars Downloading: clojure/java-time/clojure.java-time/0.3.2/clojure.java-time-0.3.2.jar from clojars Clojure 1.10.1 user=> (require '[java-time :as t]) nil user=> (str (t/instant)) "2020-09-01T03:42:47.691119Z"
Create a new directory and copy the deps.edn
file you created above into it:
$ mkdir hello-world $ cp deps.edn hello-world $ cd hello-world $ mkdir src
By default, the clj
tool will look for source files in the src/
directory.
Create src/hello.clj
:
(ns hello (:require [java-time :as t])) (defn time-str "Returns a string representation of a datetime in the local time zone." [instant] (t/format (t/with-zone (t/formatter "hh:mm a") (t/zone-id)) instant)) (defn run [opts] (println "Hello world, the time is" (time-str (t/instant))))
This program has an entry function run
that can be executed by clj
using
‘-X’:
$ clj -X hello/run Hello world, the time is 10:53 PM
You might decide to move part of this application into a library. The clj
tool uses local coordinates to support projects that exist only on your local
disk.
Let’s extract the java-time
parts of this application out into a library in a
parallel directory time-lib
. The final structure will look something like
this:
├── time-lib │ ├── deps.edn │ └── src │ └── hello_time.clj └── hello-world ├── deps.edn └── src └── hello.clj
Under time-lib
, use a copy of the deps.edn
file you already have, and
create a file src/hello_time.clj
:
(ns hello-time (:require [java-time :as t])) (defn now "Returns the current datetime" [] (t/instant)) (defn time-str "Returns a string representation of a datetime in the local time zone." [instant] (t/format (t/with-zone (t/formatter "hh:mm a") (t/zone-id)) instant))
Update the application at hello-world/src/hello.clj
to use your library
instead:
(ns hello (:require [hello-time :as ht])) (defn run [opts] (println "Hello world, the time is" (ht/time-str (ht/now))))
Modify hello-world/deps.edn
to use a local coordinate that refers to the root
directory of the time-lib
library (make sure to update the path for your
machine):
{:deps {time-lib/time-lib {:local/root "../time-lib"}}}
You can then test everything from the hello-world directory by running the application:
$ clj -X hello/run Hello world, the time is 02:07 PM