当使用socket repl时,测试运行器的输出被绑定到clojure.test的第一个加载的*out*
绑定
(def ^:dynamic *test-out* *out*)
这意味着当连接到socket-repl时,测试输出将进入控制台而不是repl会话的*out*
。
clojure.main/repl
有一个:init
选项,希望能够设置这个动态变量。
在repl中,如果手动使用with-bindings
,它将正确地绑定*test-out*
。但尝试使用clojure.main/repl
的:init
选项似乎无法绑定变量。
user=> (with-bindings {#'clojure.test/*test-out* *out*}
(identical? clojure.test/*test-out* *out*))
true
user=> (clojure.main/repl
:read server/repl-read
:init (fn [] {#'clojure.test/*test-out* *out*}))
user=> (identical? clojure.test/*test-out* *out*)
false
我通过以下方式解决这个问题
user=> (clojure.main/repl
:read server/repl-read
:eval (fn [f] (binding [clojure.test/*test-out* *out*] (eval f))))
user=> (identical? clojure.test/*test-out* *out*)
true
但我更愿意像预期那样使用:init
而不是在每个评估时进行劫持。我不确定为什么绑定不起作用。
编辑
我不确定我能否使init起作用
user=> (def ^:dynamic *foo*)
#'user/*foo*
user=> (with-bindings ((fn [] {#'*foo* 3}))
*foo*)
3
user=> (clojure.main/repl
:read server/repl-read
:init (fn [] {#'*foo* 3}))
user=> *foo*
#object[clojure.lang.Var$Unbound 0x6dcfc7b9 "Unbound: #'user/*foo*"]
现在我明白了。clojure.main中的with-bindings
使用的是clojure.main/with-bindings而不是clojure.core/with-bindings。