clojure - 在运行时设置 Clojure "constants"

标签 clojure runtime constants

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

我可以使用以下代码在运行时从 JAR list 轻松读取此内容:

(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"))))

但有人告诉我,在 defn 中使用 def 是一种恶业。

在运行时设置常量的 Clojure 惯用方法是什么?显然,我没有将构建版本信息作为 def 嵌入到我的代码中,但我希望它在 main 函数中设置一次(并且一劳永逸)程序开始。然后它应该可以作为其余正在运行的代码的 def 使用。

更新:顺便说一句,Clojure 一定是我一段时间以来遇到的最酷的语言之一。向里奇·希基致敬!

最佳答案

我仍然认为最简洁的方法是在应用程序的 main 方法中使用 alter-var-root

(declare version)

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

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

关于clojure - 在运行时设置 Clojure "constants",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3997910/

相关文章:

clojure - 理解 Mini-Kanren 的执行模型

emacs - 粘贴 clojure 评估结果时如何使 emacs 键盘宏正常工作?

clojure - clojure 1.3 中有哪些重大变化?

c - 被误解的代码示例

c++ - 从函数返回类型中删除 const 是否会破坏 ABI?

clojure - 重新绑定(bind)会令人反感吗?

c# - "A namespace cannot directly contain members such as fields or methods"文件 : controller with context

c++ - 具有重复符号的 C++ 插件库上的段错误

c++ - 如何检查是否在运行时定义了 C++ 抽象方法

c++ - 这是对 const_cast 的有效使用吗?