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

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

0

评论人:stevenruppert

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

0

评论人:jafingerhut

Clojure长期以来有一个特性,它不会对一切非法操作抛出异常。

0

评论人:stevenruppert

是的,但read-string确实会这样做。为什么"keyword"函数不可以抛出异常呢?考虑到符号名称内命名空间的其他特殊规则,"keyword"函数真的应该进行验证。

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

https://groups.google.com/forum/?fromgroups=#!topic/clojure/Ct5v9w0yNAE中对此话题有一些旧的讨论。

0

评论人:jafingerhut

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

斯蒂文,我认为可能有两个担忧:(1) 进行此类检查会比不进行检查慢,(2) 实现此类检查意味着如果/当合法符号、关键字、命名空间名称等的规则更改时,必须对其进行更新。

您是否有兴趣编写适用于 contrib 库的symbol和keyword等函数的严格版本?以及测试套件,试图测试大量的角落案例?我指的是严肃的问题,而不是修辞问题。这将允许人们想要使用这些函数的严格版本,同时很容易测量严格和宽松版本之间的性能差异。

0

评论人:stevenruppert

回顾这个问题,问题的根源是 {pr} 函数,尽管它默认“以一种对象可以被读取器读出的方式打印(link: s)”(link: 0),但并不总是这样做。因此,最容易的“解决方案”是更改其文档字符串以警告并非所有关键字都可以被读取回。

更深层次的问题是 symbol 没有一个可以表示所有实际可能的符号的读取器形式(在这种情况下,包含“@”的符号)。将实际可能的符号限制为与读取器形式匹配,即编写严格的"keyword" 函数,对我来说似乎是一个更糟的整体解决方案。更好的解决方案是某种程度上扩展关键字读取器形式,使其能够表示所有可能的符号,可能是Ruby的`:keyword`语法。此外,该解决方案将避免不得不保持假设的严格关键字/symbol函数与读取器操作同步,并为其编写测试用例等。

因此,这个bug的解决方案取决于我们愿意走多远。更改文档字符串将是最容易的方法,但扩展关键字形式对我来说是“最佳”的解决方案。

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

0
by

评论人:jafingerhut

我昨天偶然发现了工单 CLJ-17。它的讨论线程显示,关于验证构造关键字和符号内容的话题之前已经出现过。当时编写了一个补丁,修改了“symbol”和“keyword”这两个函数,使得符号/关键字按现在的构造方式构建,然后使用 clojure.lang.RT/readString 方法在字符串参数上进行了双检查,以确保可读性。如果 intern 和 readString 方法返回不同的符号(或者如果 readString 抛出异常),则会抛出一个异常。

Rich 担心这种运行时的开销会太高,并询问是否有人知道更快的方式来完成这项工作。Chas Emerick 提出了使用类似 Common Lisp 的 #|symbol with whitespace| 语法,并对引号不必要的常见情况进行了一些检查。Rich 对引用任意符号的想法持开放态度,但是这是一个不同的工单。

我并不确定自那时以来是否有人创建了用于引入任意符号引用的工单,但是我可能错过了。这个工单可能成为那个工单,但是其描述需要大幅编辑,并且需要在不同地方的 Clojure 中进行代码更改。

0
by
参考:[https://clojure.atlassian.net/browse/CLJ-1033](https://clojure.atlassian.net/browse/CLJ-1033) (报告者:ale IMPORT)
...