0

虽然我的lein 新应用程序项目在 Light Table 中愉快地运行,但 lein uberjar将无法工作。奇怪的是,它的行为与经典的 Pascal 编译器完全一样:它无法在定义之前解析引用。另一个好奇心:昨天它起作用了。我不知道在愚弄任何敏感的东西。

谷歌表示主题症状很常见;我尝试了任何可以帮助处于相同(?)困境中的其他人的方法,但无济于事。顺便说一句,他们通常将其归咎于软件错误:“获取最新版本的 Leiningen 和 Clojure”。我有 2.5.0 和 1.6。

项目(主文件)在这里:https ://github.com/Tyrn/pcc/blob/master/src/pcc/core.clj 事实上,parsed-args无法在build-album中解析;如果我将 -main 函数移动到文件顶部,则 -main 中的cli-options会发生“没有这样的 var” 。显式使用命名空间的任何摆弄都没有任何区别。

同样,在 Light Table 内,一切运行良好。

4

1 回答 1

1

在函数内部使用def不是惯用的,尤其是在没有理由将其作为全局变量的情况下。只需将其作为函数参数传递:

(let [parsed-args (parse-opts ...)]
  ...
  (build-album parsed-args))

如果你真的需要全局状态,你可以使用例如一个承诺(或者,一个原子):

(defonce parsed-args (promise))
...
(deliver parsed-args (parse-opts ...))

但是,Clojure 文件是从上到下读取的,是的,无法访问文件后面介绍的绑定的函数是设计使然。你可以declare用来告诉解析器会发生什么:

(declare ^:dynamic *parsed-args*)
(defn build-album ...)
(def ^:dynamic *parsed-args* ...)
...
(binding [*parsed-args* (parse-opts ...)]
  (build-album))

TL;DR:如果没有必要,避免全局状态;如有必要,将其最小化。

于 2014-11-15T22:26:57.037 回答