如何在AOT编译之前设置动态变量 [英] How to set a dynamic var before aot compile
问题描述
我想在给定的命名空间中有一个 * flag *
变量,该变量仅在:aot
编译时设置为 true
.
I want to have a *flag*
variable in a given namespace that is set to true
only when :aot
compiling.
有没有办法做到这一点?
Is there a way to do that?
推荐答案
您的问题有点复杂,因为Clojure自身的动态性质的定义,因此它与C的 #ifdef
几乎不存在等效性编译时发生的其他机制,但这是一种解决方法:
Your issue is kind of complicated because the definition of Clojure's own dynamic nature, so there's no rough equivalent of C's #ifdef
or some other mechanism that happens at compile time, but here's a workaround:
我用 lein新应用程序flagdemo
创建了一个Leiningen项目.此技巧将使用动态var * compile-files *
来检测何时执行AOT(如上述@Biped Phill),并将资源保存在已编译代码的类路径中:
I created a Leiningen project with lein new app flagdemo
. This trick detects when AOT is performed, as @Biped Phill mentioned above, using the dynamic var *compile-files*
, and saves a resource in the classpath of the compiled code:
代码如下:
(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中时,它将尝试写入值 false
.
So, when the file loads using, say, lein run
or when you load it in the REPL, it will try to write an EDN file with the value false
.
使用 lein uberjar
编译软件包时,它将加载名称空间并发现已定义 * compile-files *
,因此它将保存打包的EDN文件以JAR作为资源.
When you compile the package using lein uberjar
, it loads the namespace and finds that *compile-files*
is defined, thus it saves an EDN file that is packaged with the JAR as a resource.
函数 read-flag
只是尝试从类路径中加载EDN文件.
The function read-flag
just tries to load the EDN file from the classpath.
它是这样的:
$ 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
这篇关于如何在AOT编译之前设置动态变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!