从命令行一遍又一遍地运行 Clojure 脚本并不符合习惯。 REPL 是一个更好的命令行。 Clojure 是一个 Lisp,通常会启动 Clojure 并让同一个实例永远运行,并与其交互而不是重新启动它。您可以一次更改正在运行的实例中的一个函数,运行它们并根据需要插入它们。摆脱繁琐而缓慢的传统编辑/编译/调试周期是 Lisps 的一大特色。
您可以轻松地编写函数来执行诸如运行单元测试之类的操作,并且只要您想运行它们就从 REPL 调用这些函数,否则忽略它们。 Clojure 中很常见使用clojure.contrib.test-is
,将测试函数添加到命名空间中,然后使用clojure.contrib.test-is/run-tests
运行它们全部。
不从命令行运行 Clojure 的另一个充分理由是 JVM 的启动时间可能会令人望而却步。
如果您确实想从命令行运行 Clojure 脚本,有多种方法可以实现。看Clojure 邮件列表 http://groups.google.com/group/clojure/browse_thread/thread/ca60d98fb4f7e71e/ddc68367d4fa1bc7进行一些讨论。
一种方法是测试命令行参数是否存在。鉴于这种foo.clj
在当前目录中:
(ns foo)
(defn hello [x] (println "Hello," x))
(if *command-line-args*
(hello "command line")
(hello "REPL"))
根据您启动 Clojure 的方式,您会得到不同的行为。
$ java -cp ~/path/to/clojure.jar:. clojure.main foo.clj --
Hello, command line
$ java -cp ~/path/to/clojure.jar:. clojure.main
Clojure 1.1.0-alpha-SNAPSHOT
user=> (use 'foo)
Hello, REPL
nil
user=>
See src/clj/clojure/main.clj
如果您想了解其工作原理,请参阅 Clojure 源代码。
另一种方法是将代码编译为.class
文件并从 Java 命令行调用它们。给定一个源文件foo.clj
:
(ns foo
(:gen-class))
(defn hello [x] (println "Hello," x))
(defn -main [] (hello "command line"))
建立一个目录来存放编译好的.class
文件;这默认为./classes
。您必须自己创建此文件夹,Clojure 不会创建它。还要确保您设置$CLASSPATH
包括./classes
以及包含源代码的目录;我假设foo.clj
位于当前目录中。所以从命令行:
$ mkdir classes
$ java -cp ~/path/to/clojure.jar:./classes:. clojure.main
Clojure 1.1.0-alpha-SNAPSHOT
user=> (compile 'foo)
foo
In the classes
您现在将拥有一堆目录.class
文件。从命令行调用您的代码(运行-main
默认功能):
$ java -cp ~/path/to/clojure.jar:./classes foo
Hello, command line.
有很多关于编译 Clojure 代码的信息clojure.org http://clojure.org/compilation.