已创建多个工单,建议clojure.set命名空间中的几个函数在给定的参数不是集合时可能会抛出异常,因为它们在某些情况下返回了意外的值。此列表是一个示例,并非旨在全面:CLJ-810、CLJ-1682、CLJ-1953、CLJ-1954
现在有了clojure.spec,可以更准确地记录这些函数期望的参数类型。规格可以用作在测试期间动态检测传递给这些函数的错误参数类型,以及在未来基于clojure.spec的任何其他方式。
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 ...)调用中)。在它们中的一小部分上,我放弃了在不到一分钟内弄清楚答案的尝试,因为从代码审查中完全确定答案需要回溯调用树。
请提出其他可以评估这些更改的方法,以提高您确信它们是正确的信心。