【问题标题】:Clojure symbol evaluation errorClojure 符号评估错误
【发布时间】:2012-01-15 10:00:13
【问题描述】:

所以我目前有这个代码:

(ns contact-form.core
  (:gen-class))

(def foo "Hello World!")

(defn some-func [a-symbol]
  (println (str a-symbol "'s value is: " (eval a-symbol))))

(defn -main [& args]
  (some-func 'foo))

在 Emacs 中执行 C-c C-k 后,我得到以下输出:

contact-form.core> (-main)
foo's value is: Hello World!
nil

但是当我执行lein uberjar 并运行生成的 jar 文件时,我得到一个错误:

Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0)
    at clojure.lang.Compiler.analyze(Compiler.java:6235)
    at clojure.lang.Compiler.analyze(Compiler.java:6177)
    at clojure.lang.Compiler.eval(Compiler.java:6469)
    at clojure.lang.Compiler.eval(Compiler.java:6431)
    at clojure.core$eval.invoke(core.clj:2795)
    at contact_form.core$some_func.invoke(core.clj:7)
    at contact_form.core$_main.doInvoke(core.clj:10)
    at clojure.lang.RestFn.invoke(RestFn.java:397)
    at clojure.lang.AFn.applyToHelper(AFn.java:159)
    at clojure.lang.RestFn.applyTo(RestFn.java:132)
    at contact_form.core.main(Unknown Source)
Caused by: java.lang.RuntimeException: Unable to resolve symbol: foo in this context
    at clojure.lang.Util.runtimeException(Util.java:156)
    at clojure.lang.Compiler.resolveIn(Compiler.java:6720)
    at clojure.lang.Compiler.resolve(Compiler.java:6664)
    at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6625)
    at clojure.lang.Compiler.analyze(Compiler.java:6198)
    ... 10 more

所以我有两个问题:

  1. 为什么 uberjar 的功能与 REPL 不完全相同?
  2. 我可以做些什么来解决这个问题?

【问题讨论】:

    标签: clojure read-eval-print-loop leiningen uberjar clojure-1.3


    【解决方案1】:

    1.为什么 uberjar 的功能与 REPL 不同?

    错误“NO_SOURCE_PATH”的一个原因是您当前不在定义“foo”的命名空间中。

    为了说明:如果我在我的 REPL 中评估您的代码并执行它,它会将我置于您所期望的 contact-form.core 命名空间中,因为(ns contact-form.core) 由 REPL 评估,但如果我切换到 user命名空间并调用-main 我会产生同样的错误:

    contact-form.core=> (-main)
    foo's value is: Hello World!
    nil
    contact-form.core=> (ns user)
    nil
    user=> (contact-form.core/-main)
    CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:120) 
    user=> 
    

    因此,通过将入口点指定为 main 以执行独立的 uberjar(在 REPL 之外),这相当于从 jar 中的默认命名空间 clojure.core 调用 (contact-form.core/-main),因为 (ns contact-form.core)尚未评估。结果:main 可以使用函数的完全限定(命名空间)路径执行,但 contact-form.core 中的符号在当前默认命名空间中均不可用。

    2。修复

    解决方案是先显式切换到您的命名空间。:

    (defn -main [& args]
      (use 'contact-form.core)
      (some-func 'foo))
    

    【讨论】:

    • use 不仅仅只是切换命名空间。我推荐(binding [*ns* (the-ns 'contact-form.core)] (some-func 'foo))
    • @chouser 太好了!先生,请考虑我的启迪! :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 2012-11-19
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    相关资源
    最近更新 更多