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

欢迎!请查阅 关于 页面了解此工作方式的相关信息。

0
打印

user=> (read-string (pr-str {(keyword "key@other") :stuff}))
RuntimeException Map literal must contain an even number of forms  clojure.lang.Util.runtimeException (Util.java:170)


pr-str 输出 "{:key@other :stuff}",而 read-string 无法正确解析。pr-str 需要转义 @ 符号,或者 read-string 有必要处理关键词内的符号。

背景:我在通过 Storm bolts 传递带有电子邮件地址的 map,这些 bolt 需要 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成员,只是一个对此感兴趣的贡献者,也不了解这里做出的所有设计决策。

Steven,我认为可能的一些问题是:(1) 进行这些检查可能会比不进行检查慢,(2) 实施这些检查意味着在规则发生变化时需要更新它们,比如合法符号、关键字、命名空间名称等。

你是否有兴趣编写严格版本的功能(如symbol和keyword)以添加到contrib库中?以及测试套件,试图击中规则中合法与不合法的大多数边缘情况?我意思是严肃的问题,不是修辞问题。这将允许想要使用这些函数严格版本的用户这样做,并同时使衡量严格和宽松版本之间的性能差异变得容易。

0

评论由:stevenruppert 发布

回顾这个问题,根本原因是{pr}函数虽然默认以“print(link: s)”的方式“print(link: s)”对象,可以使对象能被reader读取”(link: 0),但并不总是这样做。因此,最简单的“修复”是更改其文档字符串以提示并不是所有关键字都可以被读取回。

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

因此,这个问题的解决方案取决于我们愿意走多远。更改文档字符串是最简单的方法,但扩展keyword形式按照我个人的观点将是最“好”的解决方案。

(链接: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(由alex+import报告)
...