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

欢迎!请参阅关于 页面以获取更多有关如何使用本网站的信息。

+5
打印

因为 clojure.core/pr-str 使用 with-out-str 来捕获 pr 的输出(而 pr 不能被解析为一个可写的东西——它仅使用 out)。

如果您对懒加载数据的结果执行 pr-str,则可以使用 println 将副作用写入标准输出并与输出混杂。例如,在我的案例中,我从库 criterium 中提取基准测试并尝试将数据结构打印到文件中。解决方案将是提供一个重载的 pr/pr-str,它接受一个写入器。

这当您尝试在 EDN 中持久化程序输出时是一个难看的错误,因为随机掺杂的标准输出消息使得数据无效,不能被 read-string 解析。我们不应该需要函数是纯的才能使 pr-str 按预期工作。

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

5 个答案

0

stu发表的评论:

作为这种问题的变通方法,请使用 print-dup 或 print-method

0

ocal 发表的评论:

因此,我认为解决这个问题的一个变通方法是改变(链接: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 包装。

我想不出为什么有人过去会依赖这个功能,但这样做确实有风险(链接:https://xkcd.com/1172/ 文本:破坏某人的工作流程)。我提议(并且如果没有任何合理的理由不这样做,我将提交补丁)将 pr-str 修改为直接使用 pr-on 与字符串写入器一起使用,而不是默认使用 out。这意味着 pr-str 将不得不重新实现可变参数处理,但我想这没问题。

这样做的主要动机是 prepl 使用 pr-str 将数据编码为发送到套接字的。这意味着我的(链接:https://github.com/Olical/conjure 文本:prepl 工具)会捕获所有懒序列结果中的 out,因为在上游使用了 pr-str。对此的其他修复方法是将我的 prepl 配置为不使用 pr-str 而是我的自定义函数,但我认为这只是在回避问题。

我认为正确的方法是修复 pr-str,我认为其行为不正确或不可预期,并将只会让更多的人在未来上当。再次,我很乐意解决这个问题,但在解决这个问题之前,我想听听您的意见。

0

ocal 发表的评论:

我现在意识到所有 p...-str 函数都有这个问题,目前正在思考如何为它们中的所有解决该问题。因此,任何打印懒序列的输出都不会发送到 out。也许我可以将其分割,这样它就不会发送到 out,而是发送到可以独立回绑的另一个地方,而不使用 with-out-str。

0

ocal 发表的评论:

关于将 doall 应用到传递给 p...-str 函数的任何懒序列,怎么样?它们无论如何都需要完全解决,这样我们可以在它们被 with-out-str 包装之前解决它们。我认为这意味着内部打印函数可以保持不变,而 -str 变体只需确保在打印之前解决序列即可。我认为这不会太多改变函数的特性,但将解决所有这些问题。

至少,用户可以使用 (pr-str (doall my-seq)) 在 pr-str 调用中的 with-out-str 调用之外确保所有延迟都被解决。这可以用作临时的变通办法。

看法如何?

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