请在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。这通常是有益的;但多方法的全局性质意味着这可能会咬你(或者至少会迷惑你)。当我在纯repl中测试时,我很惊讶看到pr-str产生了不同的结果。一种打印数据结构的方法应该是连续的(不受环境的影响)和保证可读的(由edn读者),这确实是一个有用的功能。
by
啊,对了,我没有意识到这是 cider 添加的打印函数。

整个打印基础设施被设计成允许用户修改,因此我认为使其独立于环境不是一个目标。
by
当然 - 允许用户修改是关键。但明确的范围有助于最小化意外原则。

例如,edn/read 的 opts 参数使用户定义的行为清晰且易于推理。相比之下,使用 print-method,我没有修改默认行为,但其他东西却修改了——全局性地。这有很好的理由。但它很意外,而且难以追踪。
...