从源于命名空间的n-levels调用动态var时未解决
设定:
File a.clj
-----------
(ns a)
(def ^:dynamic *poof* "poof")
(def x [1 '*poof* 3])
(defn- func-wbind [new-term]
(binding [*poof* new-term]
(println (eval x))))
(defn with-term [term]
(println x)
(println (eval x)) ; <== *** FAILS HERE ***
(func-wbind term))
File b.clj
-----------
(ns b
(:require [a :refer :all]))
(defn woof-it []
(with-term "woof"))
File c.clj
-----------
(ns c
(:require [b :refer :all]))
(defn try-it []
(woof-it))
使用'c'加载REPL并在动态未解析的var上调用try-it失败。
非常感谢任何帮助。
修改:以上修改且可重复的错误。
堆栈追踪:
ERROR in (endpoint-tests) (Compiler.java:6380)
Default
expected: (map? (endpoint-abstractions ep-any "www.yahoo.com"))
actual: clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve symbol: *ph* in this context, compiling:(gl_ep/epref_tests.clj:17:1)
at clojure.lang.Compiler.analyze (Compiler.java:6380)
clojure.lang.Compiler.analyze (Compiler.java:6322)
clojure.lang.Compiler$HostExpr$Parser.parse (Compiler.java:948)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6560)
clojure.lang.Compiler.analyze (Compiler.java:6361)
clojure.lang.Compiler.analyze (Compiler.java:6322)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6555)
clojure.lang.Compiler.analyze (Compiler.java:6361)
clojure.lang.Compiler.analyze (Compiler.java:6322)
clojure.lang.Compiler$BodyExpr$Parser.parse (Compiler.java:5708)
clojure.lang.Compiler$FnMethod.parse (Compiler.java:5139)
clojure.lang.Compiler$FnExpr.parse (Compiler.java:3751)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6558)
clojure.lang.Compiler.analyze (Compiler.java:6361)
clojure.lang.Compiler.eval (Compiler.java:6616)
clojure.lang.Compiler.eval (Compiler.java:6582)
clojure.core$eval.invoke (core.clj:2852)
gl_ep.html_extract$glg_hfm_transform$fn__5320$fn__5321.invoke (html_extract.clj:35)
hickory.select$attr$fn__5193.invoke (select.clj:220)
clojure.lang.AFn.applyToHelper (AFn.java:161)
clojure.lang.AFn.applyTo (AFn.java:151)
clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
clojure.lang.RestFn.invoke (RestFn.java:408)
hickory.select$ordered_adjacent$fn__5271.invoke (select.clj:481)
hickory.select$select_next_loc.invoke (select.clj:134)
hickory.select$select_next_loc.invoke (select.clj:129)
hickory.select$select_next_loc.invoke (select.clj:127)
hickory.select$select_locs.invoke (select.clj:143)
hickory.select$select.invoke (select.clj:154)
gl_ep.html_extract$hickory_get.invoke (html_extract.clj:66)
gl_ep.html_extract$mapglg$fn__5363.invoke (html_extract.clj:76)
clojure.core$map$fn__4207.invoke (core.clj:2485)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:484)
clojure.core$seq.invoke (core.clj:133)
clojure.core$map$fn__4207.invoke (core.clj:2479)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:484)
clojure.core$seq.invoke (core.clj:133)
clojure.core$apply.invoke (core.clj:617)
gl_ep.html_extract$mapglg.invoke (html_extract.clj:73)
gl_ep.html_extract$extract.invoke (html_extract.clj:87)
gl_ep.endpoint$abstractions.doInvoke (endpoint.clj:59)
clojure.lang.RestFn.invoke (RestFn.java:423)
gl_ep.endpoint$endpoint_abstractions.doInvoke (endpoint.clj:68)
clojure.lang.RestFn.invoke (RestFn.java:423)
gl_ep.epref_tests$fn__8816$fn__8817.invoke (epref_tests.clj:10)
gl_ep.epref_tests/fn (epref_tests.clj:10)
clojure.test$test_var$fn__7145.invoke (test.clj:701)
clojure.test$test_var.invoke (test.clj:701)
clojure.test$test_all_vars$fn__7149$fn__7156.invoke (test.clj:717)
clojure.test$default_fixture.invoke (test.clj:671)
clojure.test$test_all_vars$fn__7149.invoke (test.clj:717)
clojure.test$default_fixture.invoke (test.clj:671)
clojure.test$test_all_vars.invoke (test.clj:713)
clojure.test$test_ns.invoke (test.clj:736)
clojure.core$map$fn__4207.invoke (core.clj:2487)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.Cons.next (Cons.java:39)
clojure.lang.RT.boundedLength (RT.java:1654)
clojure.lang.RestFn.applyTo (RestFn.java:130)
clojure.core$apply.invoke (core.clj:619)
clojure.test$run_tests.doInvoke (test.clj:751)
clojure.lang.RestFn.invoke (RestFn.java:408)
clojure.test$run_tests.invoke (test.clj:749)
答案 0 :(得分:4)
当您eval
表单时,该表单中的非限定符号将在运行时的当前名称空间(由clojure.core/*ns*
定义)中解析,不编译对eval
的调用的命名空间。因此,符号*poof*
在REPL名称空间中得到解析。这适用于名称空间b
,因为您在需要:refer :all
时执行了a
,从而在a/*poof*
中为b
创建了一个本地别名。 c
中不存在此类别名,因此解析符号失败。
有几种方法可以解决这个问题。您可以将x
的声明更改为使用名称空间限定符号:
(def x [1 'a/*poof* 3])`
或者,您可以在eval
到命名空间*ns*
的绑定中调用a
。
(def x [1 '*poof* 3])
(defn- local-eval [x]
(binding [*ns* (find-ns 'a)]
(eval x)))
然后通过调用eval
来取代对local-eval
的来电。
有关在评估期间如何解析符号的更详细说明,请参阅Clojure documentation。