在运行时设置Clojure"常量"

Ral*_*lph 9 runtime constants clojure

我有一个Clojure程序,我使用Maven构建为JAR文件.嵌入在JAR Manifest中的是构建版本号,包括构建时间戳.

我可以使用以下代码在运行时从JAR Manifest轻松读取:

(defn set-version
  "Set the version variable to the build number."
  []
  (def version
    (-> (str "jar:" (-> my.ns.name (.getProtectionDomain)
                                   (.getCodeSource)
                                   (.getLocation))
                    "!/META-INF/MANIFEST.MF")
      (URL.)
      (.openStream)
      (Manifest.)
      (.. getMainAttributes)
      (.getValue "Build-number"))))
Run Code Online (Sandbox Code Playgroud)

但我被告知def在内部使用是不好的业力defn.

什么是在运行时设置常量的Clojure-idiomatic方法?我显然没有将构建版本信息嵌入到我的代码中def,但我希望它main在程序启动时从函数中设置一次(并且为所有).然后它应该作为def其余运行代码的可用.

更新:BTW,Clojure必须是我在很长一段时间内遇到的最酷的语言之一.感谢Rich Hickey!

kot*_*rak 7

我仍然认为最干净的方法是alter-var-rootmain您的应用程序的方法中使用.

(declare version)

(defn -main
  [& args]
  (alter-var-root #'version (constantly (-> ...)))
  (do-stuff))
Run Code Online (Sandbox Code Playgroud)

它在编译时声明Var,在运行时设置其根值一次,不需要deref并且不绑定到主线程.你在之前的问题中没有回应这个建议.你尝试过这种方法吗?