Переменные среды, используемые в инструкциях `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 с выводом предупреждения. Во время компиляции вы увидите предупреждение, но со мной все будет в порядке. Вы также можете использовать запомненную функцию вместо задержки, чтобы отложить вычисление.

Другие вопросы по тегам