Clojure:如何在启动时从文件初始化def?

Clojure:如何在启动时从文件初始化def?,clojure,Clojure,我有下面的clojure代码来初始化我的配置结构config。 我注意到文件实际上是在编译文件时读取的,而不是在运行时读取的 对我来说,配置结构config应该是不可变的,但是,我不希望配置在JAR文件中 我该怎么做?我必须使用原子吗?如果my.config丢失,应用程序崩溃也可以 (def Config (read-string (slurp "my.config"))) 当您不希望在编译时使用它时,您必须将其包装到函数中 (defn def-my-conf [] (def Conf

我有下面的clojure代码来初始化我的配置结构config。 我注意到文件实际上是在编译文件时读取的,而不是在运行时读取的

对我来说,配置结构config应该是不可变的,但是,我不希望配置在JAR文件中

我该怎么做?我必须使用原子吗?如果my.config丢失,应用程序崩溃也可以

(def Config
  (read-string (slurp "my.config")))

当您不希望在编译时使用它时,您必须将其包装到函数中

(defn def-my-conf []
  (def Conf (blub)))
但你可以用更干净的方式:

(declare Config)

(defn load-Config []
 (alter-var-root (var Config) (blub)))
这个函数应该在主函数中调用


编辑:当然原子也是一种解决方案

当您不希望在编译时使用它时,必须将其包装到函数中

(defn def-my-conf []
  (def Conf (blub)))
但你可以用更干净的方式:

(declare Config)

(defn load-Config []
 (alter-var-root (var Config) (blub)))
这个函数应该在主函数中调用


编辑:当然原子也是一种解决方案

编写用于读取配置的函数:

(defn read-config
  []
  (read-string
   (slurp "my.config")))
然后您可以从-main调用此函数,1)将配置传递给需要它的任何函数,或2)将其存储在动态变量中,让它们直接读取:

(def ^:dynamic *config* nil)

(defn some-function-using-config
  []
  (println *config*))

(defn -main
  []
  (binding [*config* (read-config)]
    (some-function-using-config)))
选择哪一个取决于口味和情况。通过直接传递,您可以明确表示函数正在接收config,通过动态变量,您可以避免将config作为参数包含到您编写的每个函数中,而大多数函数都会传递它


这两种解决方案都适用于单元测试,因为您只需将动态变量重新绑定到您希望用于每个测试的任何配置。

编写一个函数来读取配置:

(defn read-config
  []
  (read-string
   (slurp "my.config")))
然后您可以从-main调用此函数,1)将配置传递给需要它的任何函数,或2)将其存储在动态变量中,让它们直接读取:

(def ^:dynamic *config* nil)

(defn some-function-using-config
  []
  (println *config*))

(defn -main
  []
  (binding [*config* (read-config)]
    (some-function-using-config)))
选择哪一个取决于口味和情况。通过直接传递,您可以明确表示函数正在接收config,通过动态变量,您可以避免将config作为参数包含到您编写的每个函数中,而大多数函数都会传递它


这两种解决方案都适用于单元测试,因为您可以将动态变量重新绑定到您想要用于每个测试的任何配置。

QuickBrownFox得到了答案,该文件在运行时和编译时都会被读取


我很好!那真的很酷

QuickBrownFox给出了答案,该文件在运行时和编译时都被读取


我很好!那真的很酷

文件在编译时被读取,但是你确定它在应用程序启动时没有被读取吗?是的,我确定它是编译时,因为“lein compile”如果文件不存在,则中止。我想您可能会发现它在编译时和应用程序启动时都在读取。文件在编译时读取,但您确定它在应用程序启动时也没有读取吗?是的,我确定它在编译时,因为“lein compile”如果文件不存在,则中止。我想您可能会发现它在编译时和应用程序启动时都被读取。此解决方案和下面的解决方案都有相同的问题。我需要编辑-main。如果我不想更改-main,我有哪些选项?与Clojure中的静态构造函数类似的任何内容。我没有意识到Clojure和类似于Ocaml的ML对文件中的代码何时执行有如此不同的定义?在ML中,它们在“加载”程序时执行,通常用于收集或准备全局信息。我需要编辑-main。如果我不想更改-main,我有哪些选项?与Clojure中的静态构造函数类似的任何内容。我没有意识到Clojure和类似于Ocaml的ML对文件中的代码何时执行有如此不同的定义?在ML中,它们在“加载”程序时执行,通常用于收集或准备全局信息