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

欢迎!请参阅 关于 页面以了解有关此工作的一些更多信息。

0
规范
重现


(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` 的兼容性是否是必需的:如果规范提供了一种函数使用“规范”路径(即可以指向键的路径)来完成相同的事情,那就行了。

3 个答案

0

评论由:jpmonettas 提出

我认为,与兼容性相比,更重要的是一个方法:不依赖于导致问题的 spec,来匹配 :clojure.spec.alpha/problems 和 :clojure.spec.alpha/value 中的问题。
为此,我认为知道问题是出在密钥还是值上非常重要。

目前,s/map-of 报告的路径将考虑 map-entry vec,因此 0 将是密钥而 1 将是值。

我正在尝试实施的问题的麻烦在于 :in 是 s/keys,它只报告密钥。

所以,当你看到 (link: ::k 1) 这里的问题时,你不知道问题是在 map 值还是在值是一个 seq,在 seq 位置的 1 处有问题。

0

评论由:bbrinck 提出

我同意上面的观点,并在使用 {{in}} 路径获得更多经验后,我想进一步阐述。

根据我的理解,clojure.spec 的意图不是提供易于阅读的错误消息,而是为库提供一个坚实的基础,以便以不同方式呈现错误。

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

有两个特殊案例尤其具有挑战性:指示 {{map-of}} spec 中 "key" 或 "value" 失败的整数索引,以及指示 {{coll-of}} spec 中 "key/value" 向量的位置的整数索引。

我可能只是没有正确理解 'in' 路径的工作方式,但据我所知,这对其他库作者来说是一个混淆之源。 https://groups.google.com/forum/#!topic/clojure/ppnWBJhz-R4 。另外,由于此路径在使用 {{explain}} 时显示给用户,一个不那么含糊的路径将帮助所有 spec 用户更好地理解他们的错误。

是否可以创建不经读者知道路径如何使用的明确路径?如上所述,路径 {{[:key 1]}} 只有在知道有关失败数据结构的信息时才能区分。这可能会要求用自定义记录替换整数索引。这可能需要减少简洁性和可读性,但这也可能通过新的读取宏来解决。

0
参考: https://clojure.atlassian.net/browse/CLJ-2192(bbrinck 提出)
...