Ваша проблема довольно сложна из-за определения собственной динамической природы c Clojure, поэтому нет грубого эквивалента C #ifdef
или какого-либо другого механизма, который происходит во время компиляции, но вот обходной путь:
Я создал проект Leiningen с lein new app flagdemo
. Этот трюк обнаруживает, когда выполняется AOT, как упоминалось выше @Biped Phill, используя Dynami c VAR *compile-files*
, и сохраняет ресурс в пути к классам скомпилированного кода:
Код выглядит следующим образом:
(ns flagdemo.core
(:gen-class))
(def flag-path "target/uberjar/classes/flag.edn")
(defn write-flag [val]
(try (spit flag-path (str val)) (catch Exception _)))
(defn read-flag []
(some-> (clojure.java.io/resource "flag.edn") slurp clojure.edn/read-string))
(write-flag false)
(when clojure.core/*compile-files*
(write-flag true))
(defn -main
[& args]
(println "Flag is" (read-flag)))
Итак, когда файл загружает с помощью, скажем, lein run
или когда вы загружаете его в REPL, он попытается записать файл EDN со значением false
.
Когда вы компилируете пакет, используя lein uberjar
, он загружает пространство имен и обнаруживает, что определено *compile-files*
, таким образом он сохраняет файл EDN, упакованный с JAR, в качестве ресурса.
Функция read-flag
просто пытается загрузить файл EDN из пути к классам.
Работает так:
$ lein clean
$ lein run
Flag is nil
$ lein uberjar
Compiling flagdemo.core
Created /tmp/flagdemo/target/uberjar/flagdemo-0.1.0-SNAPSHOT.jar
Created /tmp/flagdemo/target/uberjar/flagdemo-0.1.0-SNAPSHOT-standalone.jar
$ java -jar target/uberjar/flagdemo-0.1.0-SNAPSHOT-standalone.jar
Flag is true