2

我正在开发一个 webapp,它依赖于某个数据文件在运行时被 slurped。如果没有数据文件,我似乎无法编译。为什么是这样?

这是在我的 core.clj

(def my-data (slurp "my-file.txt"))

然后当我尝试编译时:

$ lein ring war

我得到了这个例外

Exception in thread "main" java.io.FileNotFoundException: my-file.txt (No such file or directory), compiling:(core.clj:24:28)

我怎样才能编译我的战争?我不需要在编译时对文件进行 slurped 甚至检查是否存在。提前致谢!

[更新]

这不是特定于 war 文件打包或环的,例如:

(ns slurp-test.core
    (:gen-class))

(def x (slurp "/tmp/foo.txt"))

(defn -main [& args]
    (println x))

然后:

 $ lein uberjar
 Compiling slurp-test.core
 (ns slurp-test.core
 Exception in thread "main" java.io.FileNotFoundException: /tmp/foo.txt (No such file or directory), compiling:(core.clj:4:8)

我怎样才能解决这个问题?

4

1 回答 1

5

编译 Clojure 源文件涉及评估所有顶级表单。事实上,这对于支持预期的语义是绝对必要的——最值得注意的是,宏不能正常工作,否则1

如果您 AOT 编译您的代码,顶级表单将在编译时进行评估,然后在您的编译代码加载时在运行时再次评估。

出于这个原因,在顶级代码中引起副作用通常不是一个好主意。如果一个应用程序需要初始化,它应该由一个函数来执行(通常-main)。


1宏是存在于标记为宏的 Var 中的函数(:macro true在 Var 的元数据中;有一个添加此条目的setMacro方法)。clojure.lang.Var宏必须清楚地可供编译器使用,因此它们必须在编译时加载。此外,在计算扩展时,宏函数可能想要调用非宏函数或以其他方式利用任意 Vars 的值,这些值是通过评估在调用宏之前发生的任何顶级代码而产生的。删除这些功能会严重削弱宏功能。

于 2013-06-05T01:27:38.507 回答