在 Clojure 中使用 repl 而不是 println
Posted
技术标签:
【中文标题】在 Clojure 中使用 repl 而不是 println【英文标题】:Use repl instead of println in Clojure 【发布时间】:2022-01-11 09:22:37 【问题描述】:假设我们需要评估源文件中的多个子句,例如
test.clj
@(def x 1)
@(def y 2)
@(def z 3)
如果我们直接使用clj
或lein repl
,则只会显示最后的评估,
user => (load-file "test.clj")
3
我们可以用println
包围它们以显示所有它们,
test-with-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
s,同时能够打印出 REPL 保护下的所有预期评估?
@Solution
感谢@Sean Corfield 的回答中的tap>
,我们可以得到如下期望的结果,
tap>
。
test-with-tap.clj
(-> @(def x 1) tap>)
(-> @(def y 2) tap>)
(-> @(def z 3) tap>)
在tap>
被add-tap
开启之前,REPL 将不会收到任何输出。
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
【问题讨论】:
【参考方案1】:我还没有机会玩tap>
。这些年来我最喜欢的是spy
函数系列in the Tupelo library。具体来说,请查看spyx
、spyx-pretty
和let-spy。
【讨论】:
艾伦,非常感谢您维护良好的精彩项目。我一定会把它添加到工具包中。【参考方案2】:tap>
可能是您正在寻找的东西 - https://clojuredocs.org/clojure.core/tap%3E - 这使您可以将完整的 Clojure 值(不仅仅是字符串)发送到注册为侦听器的任何函数,例如 Portal 之类的东西 - @987654322 @ - 这是我每天都在使用的东西,但您也可以在add-tap
中使用像println
这样简单的东西来显示每个tap>
的值。
tap>
调用可以保留在您的代码中,即使在生产中也是如此,因为使用它们几乎没有开销。
虽然tap>
返回一个布尔值,但您可以使用(doto expr tap>)
评估并返回expr
,但仍将值发送给任何点击侦听器。 tap>
是一个很棒的调试工具。
【讨论】:
非常感谢,肖恩。tap>
提供的东西比我一开始想象的还要好。以上是关于在 Clojure 中使用 repl 而不是 println的主要内容,如果未能解决你的问题,请参考以下文章
Clojure 的 Emacs/Swank/Paredit 教程
Clojure 1.8的套接字repl和nREPL之间的具体区别是什么?
Clojure 的加载字符串在 repl 中有效,但在 `lein run` 中无效