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

欢迎!有关如何使用本网站的更多信息,请参阅关于页面。

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 的集合可以提供一个映射条目的序列。在 explain 情况中,every-kv 创建的 ::kfn 使用键而不是元素索引来创建更好的路径段。kfn 假定集合的元素可以调用 `(nth entry 0)` 来获取元素。在上面的 explain 失败中,映射 {:a :b} 将在调用 nth 时引发异常。

**建议**:进行以下操作以提高对 coll 元素是映射条目要求的清晰度

**修改文档字符串,将其改为“序列到映射条目”而不是“是映射”**
**修改 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 中的文档应该更加严谨,将“关联集合”改为“映射”,但将与 Rich 商量。

0

评论者:alexmiller

更新到master版本

0

评论者:alexmiller

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

0
评论者:stu_

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


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

评论者:alexmiller

向量应当失败 - every-kv需要一个map条目的序列。这个补丁在文档字符串中进行了说明,并修复了生产explain-data时可能错误抛出的异常。我更新了标题,描述包括行为之后的explain-data,并在补丁中添加了测试。

0

评论者:alexmiller

很久以前丢失了文档字符串更改,已重新添加至-7补丁。

0

评论者:alexmiller

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

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