2010-05-14 86 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

相關問題