2024 Clojure 状态调查! 中分享您的想法。

欢迎!请参阅 关于页面 获取有关此如何工作的更多信息。

+5
打印

因为 clojure.core/pr-str 使用 with-out-str 来捕获 pr 的输出(pr 不能被解析为可写对象 - 只使用 out)。

如果您将懒加载结果 pr-str,则可以使用 println 在输出中添加副作用写至 stdout。例如,在我的情况下,我正在从 crateirum 库中提取基准测试并尝试将数据结构打印到文件。解决方案将是提供可接收 writer 的 pr/pr-str 重载。我注意到 pr-on 提供了一些功能,但它仍然是私有的。

这是一个试图在 EDN 中持久保存程序输出时的丑陋错误,因为随机穿插的 stdout 消息会使 read-string 无效。我们不应该因为 pr-str 的预期工作而需要我们的函数是纯的。

我省略了一个补丁,因为我虽然认为修复很简单,但我不确定它应该放在哪里(例如,使 pr-on 公开,更改 pr,更改 pr-str)。

5 个答案

0

评论由 stu 发布

对此,作为解决方案,使用 print-dup 或 print-method

0

评论由 olical 发布

因此,我认为解决这个问题的一种方法是更改(链接: https://github.com/clojure/clojure/blob/841fa60b41bc74367fb16ec65d025ea5bde7a617/src/clj/clojure/core.clj#L4702-L4709 文本:pr-str)以使用(链接: https://github.com/clojure/clojure/blob/841fa60b41bc74367fb16ec65d025ea5bde7a617/src/clj/clojure/core.clj#L3660-L3667 文本:pr-on)和它自己的字符串写入器。这样,本来就要输出的事物仍然可以到达目的地,如果用户真的想这么做,他们可以在with-out-str中包装调用。

我想不出过去谁会依赖这个功能,但是这确实有打破某人工作流程的风险。我建议(如果没有什么充分的理由不这么做的话,我将提交一个补丁)我们将pr-str改为直接使用pr-on与字符串写入器一起使用,而不是使用默认的out。这意味着pr-str将不得不重新实现var参数处理,但我想这是可以接受的。

这样做的主要动机是prepl使用pr-str将数据编码为发送到套接字。这意味着(链接: https://github.com/Olical/conjure 文本:prepl工具)会捕获所有使用pr-str上游的所有lazy-seq结果。对这个问题的另一种修复方法是配置我的prepl不使用pr-str而使用我自己的函数,但我觉得这样只是在回避问题。

我认为正确的做法是修复pr-str,我认为这种行为是不正确或预期的,并且将来只会让更多的人陷入困境。再次,我愿意尝试解决这个问题,但我想先听听您的意见。

0

评论由 olical 发布

我现在已经意识到所有p...-str函数都有这个问题,目前正在考虑如何解决所有这些问题。所以打印懒惰序列的输出不会被发送到out。也许我可以将它分成两部分,这样就不会被发送到out,而是发送到其他可以被单独重新绑定而不使用with-out-str的东西。

0

评论由 olical 发布

对于任何传递给p...-str函数的lazy-seq,使用doall怎么样?它们无论如何都需要完全解析,这样我们就可以在它们被with-out-str包裹之前解析它们。我认为这意味着内部打印函数可以保持原样,而-str变体只需确保在打印之前解析了序列。我认为这不会太多地改变函数的特性,但会修复所有这些问题。

至少,消费者可以使用(pr-str(doall my-seq))来确保在pr-str内部的with-out-str调用之外解析所有的懒加载。这可以用作临时解决方案。

看法呢?

0
参考:https://clojure.atlassian.net/browse/CLJ-1532(由 alex+import 报告)
...