在 Clojure 中使用 repl 而不是 println

Use repl instead of println in Clojure

假设我们需要评估源文件中的多个子句,例如

test.clj

@(def x 1)
@(def y 2)
@(def z 3)

如果我们直接使用 cljlein repl,

则只会显示最后一次评估
user => (load-file "test.clj")
3 

我们可以用println围住每一个来显示全部,

测试-println.clj

(println @(def x 1))
(println @(def y 2))
(println @(def z 3))
user => (load-file "test-with-println.clj")
1
2
3
nil

有什么更好的替代方法可以避免侵入整个源代码 println,同时能够在 REPL 的保护下打印出所有预期的评估?

@解决方案

感谢@Sean Corfield 的回答tap>,我们可以得到如下想要的结果,

测试-tap.clj

(-> @(def x 1) tap>)
(-> @(def y 2) tap>)
(-> @(def z 3) tap>)
user=> (load-file "test-with-tap.clj")
nil
user=> (add-tap @(def out (bound-fn* println)))
nil
user=> (load-file "test-with-tap.clj")
1
2
3
user=> (remove-tap out)
nil
user=> (load-file "test-with-tap.clj")
nil

tap> 可能是您正在寻找的 - https://clojuredocs.org/clojure.core/tap%3E - This lets you send full Clojure values (not just strings) to any function registered as a listener, which can be something like Portal for example - https://github.com/djblue/portal - 这是我每天都在使用的东西,但您也可以使用像 [=11 这样简单的东西=] 在 add-tap 中显示每个 tap> 的值。

tap> 调用可以保留在您的代码中,即使在生产中也是如此,因为使用它们几乎没有开销。

尽管 tap> return 是一个布尔值,您可以使用 (doto expr tap>) 来评估和 return expr 但仍然将值发送给任何点击侦听器。 tap> 是一个很棒的调试工具。

我还没有机会玩 tap>。这些年来我最喜欢的是 spy 函数族 in the Tupelo library. Specifically, check out spyx, spyx-pretty, and let-spy.