I’ve clojure running within Eclipse. I want to pass arguments to clojure when running it. In the below the arguments are available in the REPL but not in the script itself. What do I need to do such that in the below typing arg1 in the REPL will return the first argument?
Script:
(NS Test)
(def arg1 (nth *command-line-args* 0))
After clicking on the 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=>
Seems like maybe your
arg1is being defined before*command-line-args*gets a value.*command-line-args*is inclojure.core, so every namespace should be able to see it (unless you define a namespace and specifically tell it to excludecoreor exclude that var). I don’t know how Eclipse launches a REPL or how/when it loads namespaces or user code, so I don’t know the problem.But you could turn
arg1into a function, and then it should always return the current value of*command-line-args*(since it’ll be resolved at runtime, and*command-line-args*should have a value by the time you call the function).Better, if
(nth *command-line-args* 0)is really that much to type itself (which I don’t think it is, really) you could write a better function:Then use
(ARGV 0),(ARGV 1)etc. Keep in mind that vectors are themselves functions of their arguments, so you could just as easily do(*command-line-args* n)directly (once you’re sure*command-line-args*is notnil; otherwise you’ll get a NullPointerException.)Using a lot of
defs to assign names to things at the top-level is usually not idiomatic in Clojure. If you want to refer to command line arguments locally and just give them a shorter name for a while, there’slet:Again, this way
arg1should get its value at runtime (whenever you callfoo) so it should work.