在命令行中反复运行Clojure脚本并不符合惯用语法,REPL是更好的命令行。作为一种Lisp语言,通常会启动Clojure并保持同一实例永久运行,并与其交互而不是重新启动它。您可以逐个更改运行实例中的函数,根据需要运行它们并对它们进行调试。摆脱繁琐缓慢的传统编辑/编译/调试周期是Lisp的一个伟大特性。
您可以轻松编写函数来执行例如运行单元测试等操作,只需在需要运行它们时从REPL中调用这些函数并忽略其他情况即可。在Clojure中使用clojure.contrib.test-is
很常见,将您的测试函数添加到名称空间,然后使用clojure.contrib.test-is/run-tests
运行所有这些测试函数。
不从命令行运行Clojure的另一个很好的理由是JVM的启动时间可能会阻止你这样做。
如果您确实想从命令行运行Clojure脚本,则有很多方法可以做到。请参见Clojure邮件列表以获取一些讨论。
一种方法是测试命令行参数的存在。给定当前目录中的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=>
如果您想了解这是如何工作的,请查看Clojure源代码中的src/clj/clojure/main.clj
。
另一种方法是将您的代码编译成.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
在 classes
目录中,现在会有一堆 .class
文件。如果想从命令行调用你的代码(默认运行 -main
函数),请执行以下操作:
$ java -cp ~/path/to/clojure.jar:./classes foo
Hello, command line.
在 clojure.org 上有关于编译Clojure代码的大量信息。