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无法正确解析。either pr-str需要转义@符号,或者read-string需要处理关键词内的符号。

背景:我将包含电子邮件地址的映射通过Storm螺栓传递,这些螺栓需要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类似的"不允许字符的符号"文字,但这也会与命名空间的处理方式混淆。

有关这个话题的更老讨论,请参阅这里

0

评论者:jafingerhut

免责声明:我不是Clojure/core成员,只是一个感兴趣的贡献者,不知道这里做出的所有设计决定。

Steven,我认为可能有两个问题:(1)进行此类检查可能比不进行检查慢,(2)实现此类检查意味着在规则发生变化时,需要更新它们,比如关于法律符号、关键字、命名空间名称等。

你是否愿意编写适用于 contrib 库的函数(如 symbol 和 keyword)的严格版本?以及尝试测试套件,以尝试在规则的限制和允许之间找到一个重要的角落案例?这意味着 serious questions,而不是 rhetorical ones。这将允许那些想要使用这些函数严格版本的人做到这一点,同时也可以轻松测量严格和宽松版本之间的性能差异。

0

评论由:stevenruppert

回顾此事,问题的根本原因在于{pr}函数,尽管它默认情况下“以对象可以被读取器读取的方式打印(link: s)”(link: 0),但它并不总是这样做。因此,最简单的“修复”方法是将它的docstring更改为警告,指出并非所有关键字都可以被读取回。

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

因此,这个问题的解决取决于我们愿意走多远。更改docstring将是最容易的,但扩展关键字形式在我看来将是“最佳”解决方案。

(链接: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对引用任意符号的想法持开放态度,但这将与那个问题不同。

我不记得有人创建一个票来引入 arbitrary symbols 的引用,但我可能错过了。这个票可以成为那个票,但它的描述需要大幅修改,并且需要对Clojure的各种位置进行代码更改。

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