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

欢迎!请参阅 关于 页面了解更多有关此项功能的详细信息。

0
打印

user=> (read-string (pr-str {(keyword "key@other") :stuff}))
RuntimeException 地图字面量必须包含偶数个形式;clojure.lang.Util.runtimeException (Util.java:170)


pr-str 输出 "{:key@other :stuff}", read-string 无法正确解释它。要么 pr-str 需要转义 @ 符号,要么 read-string 需要能够处理关键字内部的符号。

背景:我在通过 Storm bolts 传递电子邮件地址作为键的映射,这些 bolts 需要thrift-serializable格式。使用 pr-str/read-string 组合在这类键上失败,所以我退回到 JSON 序列化。

8 答案

0

评论者:stu

The '@' 字符不是关键字或符号的有效字符(请参阅 https://clojure.org/reader)。已重新分类为增强请求。

0

评论者:stevenruppert

那么 why (keyword "keywith@") 不会抛出异常呢?这似乎与您的说法不一致。

0

评论者:jafingerhut

这是 Clojure 的一个长期特性,它不会为所有非法内容抛出异常。

0

评论者:stevenruppert

是的,但read-string明确地可以。禁止关键字函数抛出异常有什么好的理由吗?对于符号名称中命名空间的特殊规则,关键字函数真的应该进行验证。

另一个解决方案是允许类似Ruby的:"不允许字符的符号"字面量,但这也会与命名空间的处理方式混淆。

https://groups.google.com/forum/?fromgroups=#!topic/clojure/Ct5v9w0yNAE 有一些关于这个话题的较旧讨论。

0

评论者:jafingerhut

免责声明:我不是Clojure/core成员,只是一个对这里的设计决策不太了解的感兴趣的贡献者。

Steven,我认为可能有几个问题: (1) 做这样的检查可能比不做检查要慢,(2) 实现这些检查意味着如果在调整符号、关键字、命名空间名称等规则时需要更新它们。

你愿意编写用于添加到贡献库的函数(如symbol和keyword)的严格版本吗?以及尝试通过测试套件来测试规则中合法与非法的大量边界情况?我将这些问题视为严肃问题,而不是修辞问题。这将允许那些想要使用这些函数的严格版本的人使用,同时使测量严格和宽松版本之间的性能差异变得容易。

0

评论者:stevenruppert

回顾这个问题,问题的根本原因是{pr}函数,尽管它默认以“print(link: s)”的方式(link: 0)打印对象,以便可以被reader读取,但并不总是这样做。因此,最简单的“修复”是改变它的文档字符串以警告并非所有关键字都可以被读取回来。

更深层次的问题是,symbol没有可以表示所有可能关键字(在这种情况下,包含"@"的关键字)的reader形式。将可能的关键字限制为与reader形式匹配,即实际写出严格的“keyword”函数,在我看来,总体上是一个更差的解决方案。更好的解决方案可能是以某种方式扩展关键字reader形式,使其能够表达所有可能的关键字,可能类似于Ruby的"keyword"语法。另外,这种解决方案会避免需要保持假设的严格关键字/symbol函数与reader操作同步,并且编写针对这一点的测试用例等。

因此,这个漏洞的解决方案取决于我们愿意走多远。改变文档字符串是最简单的,但扩展关键字形式在我看来将是“最佳”解决方案。

(链接:0): https://docs.clojure.org/clojure_core/clojure.core/pr

0

评论者:jafingerhut

昨天我遇到了编号为CLJ-17的工单。它的讨论线程显示,此前已经讨论过验证构造的关键字和符号内容的问题。当时编写了一个补丁,修改了“symbol”和“keyword”函数,使符号/关键字按照现在的构造方式进行,但随后通过clojure.lang.RT/readString方法对给定的字符串参数进行了二次检查。如果intern和readString方法返回的符号不相等(或如果readString抛出异常),则会抛出异常。

Rich担心这种运行时开销会太高,并询问是否有人知道更快的实现方法。Chas Emerick建议使用类似Common Lisp的#|symbol with whitespace|的语法,对常见的不需要引用的情况进行一些检查。Rich对引述任意符号的想法持开放态度,但那将是另一个工单。

据我所知,此后没有人创建工单来引入对任意符号的引述,但我可能错过了。这个工单可能就是那个工单,但它的描述需要大量编辑,Clojure代码的多个地方也需要进行代码更改。

0
参考: https://clojure.atlassian.net/browse/CLJ-1033(由aleax+import报告)
...