Clojure:在脚本中使用* command-line-args *而不是REPL

时间:2010-05-14 06:57:09

标签: clojure

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

脚本:

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

点击Eclipse“Run”...

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=> 

1 个答案:

答案 0 :(得分: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)(一旦您确定{ {1}}不是*command-line-args*;否则您将获得NullPointerException。)

在Clojure中,使用大量nil来为顶级事物指定名称通常不是惯用的。如果你想在本地引用命令行参数并暂时给它们一个较短的名字,那就是def

let

同样,这种方式(defn foo [] (let [arg1 (nth *command-line-args* 0)] ...)) 应该在运行时获得它的值(每当你调用arg1时)它应该可以工作。