请分享您的想法,参加2024年Clojure状态调查!2024 State of Clojure Survey!

欢迎!请访问关于页面获取更多关于这里是怎样工作的信息。

+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中更加强大的print/read往返功能,是一个有待考虑的工作内容。
这对于1.11版本来说将是极好的。如果这有助于思考这项工作,这里是我最初提问时忽略的一个细节

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

整个打印基础设施被设计为可由用户修改,因此我认为使其和环境无关不是一个目标。
by
当然,用户可修改是关键。但明确的范围有助于最小化惊讶的原则。

例如,edn/read的opts参数使用户定义的行为清晰且易于推理。相比之下,对于print-method,我没有修改默认行为,但第三方全局地修改了。它有很好的理由。但它是一个令人惊讶且不简单追踪的问题。
...