2024 Clojure调查问卷!中分享你的想法。

欢迎!请查阅关于页面以获取更多关于此页的工作方式的信息。

+1
打印

函数的print-method实现旨在产生有效的edn语法吗?在某些情况下,它并不能

user> (require '[org.httpkit.server :as http])
user> (def s (http/run-server (fn [req] {:status 200}) {}))
user> (prn s)
#function[clojure.lang.AFunction/1]

标识符名称不能以数字开头,因此clojure.lang.AFunction/1在读取回时会引发解析错误

user> (clojure.edn/read-string (prn-str s))
Execution error at user/eval7394 (REPL:68).
Invalid token: clojure.lang.AFunction/1

这是预期的行为吗?如果是这样,在可能包含函数的数据结构中进行打印和重读可能会失败。

1 个回答

0

选择
 
最佳答案

是的,这是预期行为。函数不能以这种方式序列化,edn没有函数实例的表示方式。

我认为创建不可读的标签字面量的数字可能会被考虑成一个问题。
谢谢,Alex。我对不可读的标签字面量很感兴趣。处理标签字面量是一个单独的话题;但是我认为print-method应该能够产生符合EDN语法的文本。
一般来说,print-method并不保证产生符合语法的edn(有很多方式违反这个假设),甚至不能保证打印Clojure数据。是否支持EDN打印或以更强的方式打印/读取往返是一个在1.11版本中需要考虑的工作项。
看到1.11版本中有这个特性将是极好的。如果这有助于思考相关工作,以下是在我初次提问时忽略的细节:

不可读的标签字面量似乎不是由Clojure本身生成的。cider-nrepl为某些对象类型添加了print-method实现,包括clojure.lang.AFunction。这通常很有帮助;但由于多方法的全局性质,这可能会让你感到困惑(或者至少会让你困惑)。我惊讶地看到在vanilla repl中pr-str产生了不同的结果。一种一致的、不受环境影响的(通过edn读取器保证可读的)打印数据结构的方法将是一个非常实用的功能。
啊,对了,我没有意识到这是 cider 添加的打印函数。

整个打印基础架构设计为可由用户修改,所以我认为使其与环境无关不是目标。
当然 —— 用户体验可修改是关键。但显式作用域有助于最小化惊奇原则。

例如,edn/read 的 opts 参数使用户定义的行为清晰易懂。相比之下,使用 print-method,我没有修改默认行为,但有人修改了其他东西——全局性。它有一个很好的原因。但它令人惊讶且难以追踪。
...