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

欢迎!请参阅 关于 页面以获取更多有关本场所工作方式的详细信息。

0
Spec
every-kv 文档中指出 "接受单独的关键字和值谓词,并在关联集合上工作"。向量返回 true 对于关联? 但当前不支持


user=> (s/conform (s/every-kv any? any?) [])
[]
user=> (s/conform (s/every-kv any? any?) [1 2 3])
:clojure.spec/invalid
user=> (s/conform (s/every-kv integer? string?) [])
[]
user=> (s/conform (s/every-kv integer? string?) ["x"])
:clojure.spec/invalid


另一个类似问题


(s/explain-data (s/every-kv int? int?) [{:a :b}])
UnsupportedOperationException nth 不支持此类型:PersistentArrayMap  clojure.lang.RT.nthFrom (RT.java:903)


*原因:* 向量不应与 every-kv 一起使用。every-kv 和 every-impl 的结合假定传递给 every-kv 的集合可以提供一个地图条目的序列。在说明的情况下,由 every-kv 创建的 ::kfn 用于使用键而不是元素索引创建更好的路径段。kfn 假定集合的元素可以调用 `(nth entry 0)`。在上述说明失败的情况下,地图 {:a :b} 会抛出异常。

*建议:* 做以下改进,以更明确地说明集合元素是地图条目的要求

* 修改文档字符串,将其改为 "seq 到地图条目" 而不是 "是地图"。
* 修改 kfn 以添加检查是否为条目,如果是,则使用其键。如果不是,则使用元素的索引(本身)。在这种情况下,当传递一个条目时,它将报告实际的键,但当传递不是条目的东西时,它将报告非条目的集合基于索引。

修复后,explain-data 调用将提供有用的错误,而不是上面的异常


user=> (s/explain-data (s/every-kv int? int?) [{:a :b}])
#:clojure.spec.alpha{:problems ({:path [], :pred vector?, :val {:a :b}, :via [], :in [0]})}



*补丁:* clj-2080-8.patch

8 答案

0

评论由:alexmiller

目前,我倾向于说 every-kv 中的文档应该更严格地使用 "map" 而不是 "关联集合",但将检查 Rich。

0
by

评论由:alexmiller

更新为适用于master

0
by

评论由:alexmiller

更新补丁以适用于spec.alpha。

0
by
_由stu_发表的评论:

请更新此工单,包括描述中所示示例的预期行为以及显示预期行为的测试。  我仍然看到向量的conform失败。


(s/explain-data (s/every-kv integer? string?) ["x"])
=> #:clojure.spec.alpha{:problems ({:path [], :pred vector?, :val "x", :via [], :in [0]})}
0
by

评论由:alexmiller

向量应该失败 - every-kv需要一个映射条目的序列。该补丁在文档字符串中澄清了这一点,并修复了产生explain-data时可能(错误地)抛出的异常。我更新了标题、包括行为后的explain-data的描述,并将测试添加到该补丁中。

0
by

评论由:alexmiller

文档字符串更改丢失很久了,现在在-7补丁中重新添加。

0
by

评论由:alexmiller

-8更新适用于master,无语义更改

0
参考: https://clojure.atlassian.net/browse/CLJ-2080(由 bbloom 报告)
...