2010-05-14 87 views
2

我已经在Eclipse中运行clojure了。我想在运行时将参数传递给clojure。在下面的参数在REPL中可用,但不在脚本本身中。我需要做什么以便在REPL中的下面的键入arg1将返回第一个参数?Clojure:在脚本中使用*命令行参数*而不是REPL

脚本:

(NS Test) 
(def arg1 (nth *command-line-args* 0)) 

点击Eclipse的 “运行” 后...

Clojure 1.1.0 
1:1 user=> #<Namespace test> 
1:2 test=> arg1 
nil 
1:3 test=> *command-line-args* 
("bird" "dog" "cat" "pig") 
1:4 test=> (def arg2 (nth *command-line-args* 1)) 
#'test/arg2 
1:5 test=> arg2 
"dog" 
1:6 test=> 

回答

3

好像也许你arg1*command-line-args*之前被定义得到的值。 *command-line-args*clojure.core,所以每个名称空间应该能够看到它(除非你定义了一个名称空间并专门告诉它排除core或排除该var)。我不知道Eclipse如何启动REPL,或者它如何/何时加载命名空间或用户代码,所以我不知道这个问题。

但是你可以把arg1成一个函数,然后它应该总是返回的*command-line-args*电流值(因为它会在运行时解决,*command-line-args*应该由调用该函数时的值)。

(defn arg1 [] (nth *command-line-args* 0)) 

越好,如果(nth *command-line-args* 0)真的那么多类型本身(我不认为这是真的),你可以写出更好的功能:

(defn ARGV [n] (nth *command-line-args* n)) 

然后用(ARGV 0)(ARGV 1)等请记住,矢量本身就是它们的参数的函数,因此您可以直接轻松地执行(*command-line-args* n)(一旦确定*command-line-args*不是nil;否则您将得到NullPointerException。)

使用大量def s为顶层的事物分配名称通常在Clojure中不是惯用的。如果你想引用命令行参数本地,只是给他们一个较短的名称了一段时间,有let

(defn foo [] 
    (let [arg1 (nth *command-line-args* 0)] 
    ...)) 

同样,这样arg1将会在运行时得到其数值(只要您拨打foo),所以它应该管用。

+0

Brian,谢谢你的建议。它肯定看起来像REPL在Eclipse中开始的方式;直接运行脚本按预期工作。 仅供参考,不知道为什么,但将arg1定义为函数不能如我所料。下面是一个新的脚本和输出直接运行它。 (NS试验) (的println *命令行-ARGS *) (DEFN ARG1 [](第n *的命令行-ARGS * 0)) 并运行它... 的java -cp/Path_to_jar /clojure.jar clojure.main com.clj猫狗 (猫狗) # (println arg1) – 2010-05-15 08:59:33

相关问题