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

欢迎!请参阅关于页面了解该功能的更多信息。

+1
Spec
生成器重写在多spec时不按预期工作。
以下代码说明了问题。

{code:none}
(s/def ::obj-type #{:a :b})

(s/def ::base-obj (s/keys :req [::obj-type]))

(defmulti obj-type ::obj-type)
(defmethod obj-type :a [_]
  ::base-obj)
(defmethod obj-type :b [_]
  ::base-obj)

(s/def ::obj (s/multi-spec obj-type ::obj-type))


{code:none}
(gen/sample (s/gen ::obj {::obj-type #(gen/return :a)}))

在上面的例子中,多方法的分派函数*::obj-type*被给予一个生成器重写。
预期它只返回*{::obj-type :a}*的集合
实际上它还会返回*{::obj-type :b}*。
这意味着生成器不能用来约束从样本中分派的键集合。

h2. 当前方法
在多方法的情况下,为每个可能的分派值构造一个生成器。
然后随机选择一个值,而不考虑分派函数的(键)重写。

h2. 修补方法
提交可在[这里](https://github.com/bonega/spec.alpha/commit/9cb42478b52eac275d496ec29669e2bf4b3e8e1f)找到
修补版本 constructs generators for dispatch values exactly as original.
之后,会检查是否存在分派函数的重写。
如果有,则使用重写生成器进行gen/bind操作。
bind函数从重写生成器中生成一个值。
然后使用该值查找并返回正确的多方法生成器。

[测试用例](https://pastebin.com/62ZT5Zfc)

6 答案

0

评论者:bonega

为问题提供修补方案。

0

评论者:alexmiller

能否将问题的代码移至描述中,并解释问题和修改内容?

0
_评论者:[email protected]_

我弄不清楚如何编辑描述...

描述
在多方法的情况下,为每个可能的分派值构造一个生成器。
然后会随机选择一个,而不考虑对 dispatch-fn(key) 的覆盖。

提交: https://github.com/bonega/spec.alpha/commit/9cb42478b52eac275d496ec29669e2bf4b3e8e1f
我的补丁通过检查是否存在对 dispatch-fn 的覆盖来修复此问题。
如果是的话,会对覆盖生成器执行 gen/bind,并使用结果来查找正确的多方法生成器。

测试案例: https://pastebin.com/62ZT5Zfc
期望测试通过。
基本上我想使用类似于 `(gen/generate (s/gen ::obj {::obj-type #(gen/return :a)})` 的覆盖生成器来生成 ::obj。
期望的结果应该是 `{::obj-type :a}`。
以前,即使指定了覆盖,将 :b 作为输出也是可能的。
0

评论者:alexmiller

我已经为您提供了编辑权限,您可以对其进行更新...

0

评论者:[email protected]

我已经更新了描述。
如果有什么不清楚的地方,请告诉我。

0
...