已创建几个工单,建议 clojure.set 命名空间中的几个函数在给定非集合作为参数时可能抛出异常,因为这些函数在某些情况下会返回意外的值。此列表是一个样本,并不完整:CLJ-810、CLJ-1682、CLJ-1953、CLJ-1954。
由于 clojure.spec 存在,可以更精确地记录这些函数的预期参数类型。这些规范可以在测试期间动态检测传递给这些函数的错误参数类型,并可以通过任何基于 clojure.spec 构建的其他方式future。
Alex Miller 在 Slack 讨论中建议,如果贡献者可以帮助为 Clojure 中的函数实现此类规范,可能会有所帮助。
所提出的修补程序采用的方法很简单,就是规范 clojure.set/subset?、superset?、union、intersection 和 difference 的 :args 必须都是集合,并规范前两个的 :ret 类型为布尔值,最后三个为集合。这似乎符合在拒绝之前提出的更改这些函数行为的问题时给出的所有已知评论。
修补程序:CLJ-2287-add-clojure-set-specs-v1.patch
上述修补程序未采取的另一方法是允许参数和返回值也为 nil,但尚不清楚这是否为这些函数预期契约的一部分,还是它们当前实现的偶然方面。
我(Andy Fingerhut)查看了所有 Clojure 和 contrib 项目的 clojure.set/union、difference、intersection、superset? 和 subset? 的出现,只有一个我可以快速确定没有将集合传递给它。它是 clojure.data/diff 中的一个,关于此工单有一部分可以纠正该错误(假设它被认为是错误):CLJ-1087。
我快速确定了太多类似的调用总是传递集合(例如,因为参数被包裹在 (set ...) 调用中)。在其中的一小部分上,我在一分钟内放弃尝试弄清楚答案,因为从代码检查中完全确定答案需要回溯调用树一段距离。
请提出任何其他方法来评估这些更改以增加您对这些更改正确性的信心。