当使用 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
,而不是需要在每次评估时入侵。
EDlT
我不确定能否让 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.core/with-bindings。