请分享您对 2024 Clojure状态调查 的想法!

欢迎!请访问关于 页面获取更多关于其工作方式的信息。

+5
打印

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

如果 pr-str 了一个延迟结果,你可以通过 println 结合输出,来获取写入 stdout 的副作用。例如,在我使用库 criterium 提取基准并尝试将数据结构打印到文件的情况下。解决方案是提供一个接受 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)结合其自己的字符串写入器。这样,打算输出的事物仍然会被输出,如果用户确实想要那样做,他们可以封装 calls with-out-str。

我无法想象为什么有人会依赖过去的功能,但这种做法具有(链接:https://xkcd.com/1172/ 文本:破坏某人的工作流程)的风险。我建议(并且在没有充分的理由不这样做的情况下将提交补丁)我们将 pr-str 更改为直接使用 pr-on 与字符串写入器关联,而不是默认的 pr 关联到 out。这意味着 pr-str 将不得不重新实现 var args 处理,但我觉得这没关系。

这主要是因为 prepl 使用 pr-str 来将数据编码为发送到套接字的内容。这意味着我的(链接:https://github.com/Olical/conjure 文本:预配置工具)将捕获所有 lazy-seq 结果,因为 pr-str 在上层使用。另外一种修复方法是为我的 prepl 安装不使用 pr-str 而用我的函数进行配置,但我认为这只是在回避问题。

我认为正确做法是修复 pr-str,我认为其行为不正确或不符合预期,并将只是在未来使更多的人陷入困境。同样,我很乐意尝试修复这个,但在做之前我想先听听您的意见。

0

由 olical 创建的评论

现在我意识到所有 p...-str 函数都有同一问题,目前正在考虑如何解决所有这些问题。所以任何打印 lazy-seq 都不会将其输出发送到 out。也许我可以分割这部分,使其不会发送到 out 而发送到其他可以单独重新绑定的事物,而无需使用 with-out-str。

0

由 olical 创建的评论

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

至少,用户可以使用(pr-str (doall my-seq))来确保在 pr-str 中的 with-out-str 调用之外解析所有延迟性。这可以用作临时解决方案。

有何看法?

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