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

欢迎!请查看关于页面,了解更多如何使用本网站的信息。

0
规约
*描述*

如果您为一个函数添加了instrument,可能会得到如下样的spec错误


(defn f [x] (inc x))
(s/fdef f
  :args (s/cat :x (s/and integer? even?))
  :ret (s/and integer? odd?))

(t/instrument)

(f 3)
;; ExceptionInfo 请求#'user/f时没有符合spec
;; In: [0] val: 3 在: [:args :x] 断言: even?
;; :clojure.spec.alpha/spec  #object[clojure.spec.alpha$regex_spec_impl$reify__1200
 0x19b3f9a "clojure.spec.alpha$regex_spec_impl$reify__1200@19b3f9a"]
;; :clojure.spec.alpha/value  (3)
;; :clojure.spec.alpha/args  (3)
;; :clojure.spec.alpha/failure  :instrument
;; :clojure.spec.test.alpha/caller  {:file "form-init3240393046310519022.clj", :lin
e 1, :var-scope user/eval1413}
;; clojure.core/ex-info (core.clj:4725)

(ex-data *e)
;; {:clojure.spec.alpha/problems
;;   [{:path [:args :x],
;;     :pred clojure.core/even?,
;;     :val 3,
;;     :via [],
;;     :in [0]}],
;;  :clojure.spec.alpha/spec #object[clojure.spec.alpha$regex_spec_impl$reify__1200 0x19b3f9a "clojure.spec.alpha$regex_spec_impl$reify__1200@19b3f9a"],
;;  :clojure.spec.alpha/value (3),
;;  :clojure.spec.alpha/args (3),
;;  :clojure.spec.alpha/failure :instrument,
;;  :clojure.spec.test.alpha/caller {:file "form-init3240393046310519022.clj", :line 1, :var-scope user/eval1413}}


如您所见,

- explain-data包含一个正则表达式(即f的参数的spec)作为{{::s/spec}}
- 每一个问题在它们的{{:path}}中包含{{:args}}

这些事实可能会导致spec错误报告器的混淆,因为{{f}}({{(s/and integer? even?)}})的参数的spec没有与{{:args}}键对应的子spec(我相信{{:path}}应该只包含可以作为选择spec中哪个子spec的线索的键)。

*可能的解决方案*

为了解决这种情况的混淆并提高instrument检查中explain-data的一致性,我认为有两种选择,如下:

- *解决方案1.* 从{{:path}}中移除{{:args}}
- *解决方案2.* 修改instrument检查的explain-data,使它们有fspec(而不是它的{{:args}})作为{{::s/spec}}

我个人更喜欢*解决方案2*,因为在explain-data中添加fspec可以使提供更丰富的错误信息给{{\*explain-out\*}}实现者成为可能。

同样也适用于{{macroexpand-check}}。

6 答案

0

评论由:alexmiller 制作

在这里,“fspec”指的是有疑问的规格,它确实有一个组件:args(fspec实例支持通过ILookup来对:args进行键查找)。因此,虽然我想改进这里的错误信息和数据,但我不赞同从路径中删除:args。我认为一个有用的改进是,在仪器故障中更好地指明调用(将函数和参数组合到原始调用中)。目前它们是分开的,需要做一些精神上的工作来将参数列表重新组合。

0

评论由:sohta 制作

{quote}
因此,虽然我想改进这里的错误信息和数据,但我不同意从路径中删除:args。
{quote}

是的,所以一旦我们决定采用解决方案2,我认为就没有必要从:path中删除{{:args}}。

{quote}
我认为一个有用的事情是,在仪器故障中更好地说明调用(将函数和参数组合成原始调用)。
{quote}

我完全同意这样做很有用,尽管这听起来可能有点超出票据的一致性改进范围。

0

评论由:sohta 制作

我已经制作了一个补丁来表示我的意思。任何反馈都将被欢迎。

0

评论由:bbrinck 制作

{quote}
我认为对于仪器故障更好地说明调用(将函数和参数组合成原始调用)将是有用的。目前它们是分开的,需要做一些精神上的工作来将参数列表重新组合。
{quote}

很抱歉如果遗漏了什么,但从explain-data中获取函数是否甚至可能?我在explain-data中没有看到它,但也许它可以以某种方式恢复?无论如何,如果此类信息可用,这将有可能打印出更清晰的错误信息。

0

评论由:sohta 制作

嘿,这是否已经被CLJ-2392? :)

0
...