When using a socket repl, the output from the test runner is bound to the *out*
of binding which first loads clojure.test:
(def ^:dynamic *test-out* *out*)
This means that when connecting a socket-repl the test output will go to the console rather than the *out*
of the repl session.
clojure.main/repl
has an :init
option that I was hoping to be able to set this dynamic var.
In a repl, if I manually use with-bindings
it correctly binds *test-out*
. But trying to use the :init
option of clojure.main/repl
seems to fail to bind the var.
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
I work around this with
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
But I would prefer to use the :init
as it is intended and not have to hijack each eval. I'm not sure I understand why the binding doesn't take effect.
EDIT:
I'm not sure i'm able to make the init work at all:
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*"]
I see why now. The with-bindings
used in clojure.main is not clojure.core/with-bindings.