2024 Clojure状况调查中分享你的看法!

欢迎!请查阅关于页面以了解更多关于如何使用本站的信息。

0
REPL
编辑

当使用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。

1 答案

0

答案:误解。《code>clojure.main/repl使用的是(with-bindings (init) ...),但它不是clojure.core/with-bindings,而是clojure.main/with-bindings。

...