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

欢迎!请参阅关于页面以获取有关这个站点工作方式的更多信息。

0
Spec
重现


(require '[clojure.spec.alpha :as s]
(s/def :foo/user-map (s/map-of string? int?))
(s/explain-data :foo/user-map {"hi" "foo"})
;; 实际值
;; #:cljs.spec.alpha{:problems
;;                 ({:path [1],
;;                   :pred int?,
;;                   :val "foo",
;;                   :via [:foo/user-map],
;;                   :in ["hi" 1]})}
;; 预期:`:in` 值为 ["hi"] 吗?
(s/explain-data :foo/user-map {:hi 2})
;; 实际值
;; #:cljs.spec.alpha{:problems
;;                 ({:path [0],
;;                   :pred string?,
;;                   :val :hi,
;;                   :via [:foo/user-map],
;;                   :in [:hi 0]})}
;; 预期:我不太确定,因为路径不能“指向”键


动机:给定一些顶层数据(在这个例子中,`{"hi" "foo"}`)和 `:in` 路径,我希望能够找到有问题的数据(在这个例子中,“foo”)。

在这种情况下,如果映射的值不符合,`:in` 路径与 `get-in` 等函数不兼容,但也可能是。

在这种情况下,如果映射的键不符合,则无法使用 `get-in` 指向键,因此我不确定正确的修复方法。

我不知道与 `get-in` 的兼容性是否是必需的:如果规范提供了一个函数,它可以用“spec”路径(即可以指向键的路径)完成相同的事情,那就很好了。

3 答案

0

评论者:jpmonettas

我认为,与兼容性相比,一种匹配 :clojure.spec.alpha/problems 的方式更为重要,这种匹配是在 :clojure.spec.alpha/value 中独立于导致问题的规范进行的。
对此,我认为了解问题是在键还是在值上是非常重要的。

目前,s/map-of 报告一个路径时,考虑了 map-entry 向量,因此 0 将是键,1 将是值。

我试图实现的问题在于 :in 是 s/keys,它只报告键。

因此,当你看到 (link: ::k 1) 中的问题时,你不知道这是在 map 值出现问题,还是值是一个序列,问题在这个序列的第一个位置。

0

评论者:bbrinck

我同意上面的说法,在更多使用 {{in}} 路径的经验之后,我想进一步说明。

AIUI,clojure.spec 并不旨在提供易于阅读的错误消息。相反,它旨在提供一个坚实的基础,以便库可以以不同的方式呈现错误。

在我的经验中,尝试以不同的方式呈现错误(Expound)时,我可以报道,尝试解释 {{in}} 路径的一个最大挑战。

有几种情况特别具有挑战性:在 {{map-of}} 规范中指示“键”或“值”失败的整数索引,以及在 {{coll-of}} 规范中指示“键/值”向量位置的整数索引。

我可能只是在没有正确理解 'in' 路径的工作方式,但以轶事为证,这是其他库作者困惑的原因之一。[这里有一个链接](https://groups.google.com/forum/#!topic/clojure/ppnWBJhz-R4)。此外,由于这个路径在使用 {{explain}} 时显示给用户,因此一个不模糊的路径将有助于所有规范用户更好地理解他们的错误。

是否可以创建不模糊的路径,而不需要读者了解任何关于路径使用方式的信息?如上所述,路径 {{[:key 1]}} 只能通过了解失败的数据结构来区分。这很可能需要用自定义记录替换整数索引。这将降低简洁性和可读性,但可能可以通过新的读取器宏来缓解。

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