Leiningen, repl, uberjar: невозможно разрешить символ, нет такой переменной

Хотя мой проект lein new app весело работает внутри светового стола, lein uberjar работать не будет. Любопытно, что он ведет себя точно так же, как классический компилятор Pascal: он не может разрешать ссылки перед определениями. Еще любопытство: вчера все работало. Я не знаю, как обманывать что-то чувствительное.

Google говорит, что симптомы subj довольно распространены; Я пробовал все, что помогало другим людям в таком же (?) Затруднительном положении, но безрезультатно. Кстати, обычно винят в этом программные баги: «получите последнюю версию Leiningen и Clojure». У меня 2.5.0 и 1.6.

Проект (основной файл) находится здесь: https://github.com/Tyrn/pcc/blob/master/src/pcc/core.clj Как бы то ни было, parsed-args не может быть разрешен внутри build-album; если я перемещу функцию -main в начало файла, с cli-options внутри -main произойдет сообщение «Нет такой переменной». Никакая возня с явным использованием пространств имен не имеет значения.

Опять же, внутри светового стола все работает нормально.


person Alexey Orlov    schedule 15.11.2014    source источник


Ответы (1)


Использование def внутри функции не идиоматично, особенно если нет причин использовать его в качестве глобальной переменной. Просто передайте его как параметр функции:

(let [parsed-args (parse-opts ...)]
  ...
  (build-album parsed-args))

Если вам действительно нужно глобальное состояние, вы можете использовать, например. обещание (или атом):

(defonce parsed-args (promise))
...
(deliver parsed-args (parse-opts ...))

Однако файлы Clojure читаются сверху вниз, и да, функции, не имеющие доступа к привязкам, представленным позже в файле, являются преднамеренными. Вы можете использовать declare, чтобы сообщить парсеру, чего ожидать:

(declare ^:dynamic *parsed-args*)
(defn build-album ...)
(def ^:dynamic *parsed-args* ...)
...
(binding [*parsed-args* (parse-opts ...)]
  (build-album))

TL;DR: если нет необходимости, избегайте глобального состояния; при необходимости свести к минимуму.

person xsc    schedule 15.11.2014
comment
Большое спасибо, xsc! Почему-то я не мог заставить себя поверить, что декларации могут существовать на таком тщательно интерпретируемом языке. Несмотря на очевидное. - person Alexey Orlov; 16.11.2014