Clojure: использование * командной строки-args * в сценарии, а не REPL - PullRequest
2 голосов
/ 14 мая 2010

Я заткнулся в Eclipse. Я хочу передать аргументы для закрытия при запуске. В приведенных ниже аргументах доступны в REPL, но не в самом скрипте. Что мне нужно сделать, чтобы в приведенном ниже наборе arg1 в REPL вернул первый аргумент?

Сценарий:

(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 Ответ

3 голосов
/ 14 мая 2010

Похоже, что ваш arg1 определен до того, как *command-line-args* получит значение. *command-line-args* находится в clojure.core, поэтому каждое пространство имен должно его видеть (если только вы не определили пространство имен и не указали, что оно исключает core или исключает эту переменную). Я не знаю, как 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), поэтому он должен работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...