Переменные среды, используемые в инструкциях `def` в Clojure
У меня есть этот кусок кода:
(def heavy_computation (f1 (env :var1)))
где (env :var1)
извлекает переменную окружения VAR1
(с помощью окружения), которое указывает на местоположение каталога и f1
является оберткой вокруг функции Java Это используется позже в функциях, и это тяжелые вычисления, которые я хотел бы вычислить только один раз.
Я хочу иметь возможность настроить VAR1
и распечатать сообщение об ошибке, если оно отсутствует в производстве.
Если я скомпилирую этот код lein uberjar
без переменных окружения выдает ошибку об NullPointerException
на этой линии.
Я могу скомпилировать его с переменными среды, и позже, если я установлю их соответствующим образом, это будет работать. Чтобы напечатать мое сообщение об ошибке в случае его отсутствия, я должен поставить код, который проверяет его прямо перед def
оператор, в противном случае он выдает исключение нулевого указателя.
Могу ли я сделать это более чистым способом? Я не хочу устанавливать переменные окружения для его компиляции, и я хочу поместить код, который выполняет проверки в -main
функционировать прямо перед запуском сервера.
2 ответа
Одним из вариантов является завершение оценки в delay
:
(def heavy-computation (delay (f1 (env :var1))))
Тогда везде, где вам нужен результат, вы можете deref
/ @
задержка:
(when (= :ok @heavy-computation)
(println "heavy!"))
delay
Тело будет оцениваться только один раз, а не до тех пор, пока вы не разыграете его.
Оберните значение среды в if-let и обработайте ветку else с выводом предупреждения. Во время компиляции вы увидите предупреждение, но со мной все будет в порядке. Вы также можете использовать запомненную функцию вместо задержки, чтобы отложить вычисление.