Clojure: using * command-line-args * in script, not REPL

I have clojure running in Eclipse. I want to pass arguments to clojure when it runs. The below argument is available in the REPL, but not in the script itself. What do I need to do so that in the below set arg1 in the REPL will return the first argument?

Script:

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

      

After clicking on 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=> 

      

+2


a source to share


1 answer


It looks like yours arg1

is being defined before it *command-line-args*

gets the value. *command-line-args*

is in clojure.core

, so every namespace should be able to see it (unless you define a namespace and tell it to exclude core

or exclude this var). I don't know how Eclipse starts the REPL or how / when it loads namespaces or user code, so I don't know the problem.

But you can turn arg1

into a function, and then it should always return the current value *command-line-args*

(since it will be resolved at runtime, but *command-line-args*

should have a value by the time the function is called).

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

      

Better if it is (nth *command-line-args* 0)

really typing itself so hard (which I don't think it is), you could write a better function:

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

      



Then use (ARGV 0)

, (ARGV 1)

etc. Keep in mind that vectors are themselves functions of their arguments, so you can just as easily do it (*command-line-args* n)

directly (once you're sure *command-line-args*

not nil

; otherwise you'll get a NullPointerException.)

Using a lot def

to name things at the top level is usually not idiomatic in Clojure. If you want to refer to the command line arguments locally and just give them a short name for a while, then let

:

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

      

Again, this way arg1

should get its value at runtime (whenever you call foo

), so it should work.

+3


a source







All Articles