已创建了几个工单,建议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 ...)中)总是传递集合。在很小的一部分中,我花了不到一分钟就放弃尝试确定答案,因为完全从代码检查中确定答案需要回溯调用栈相当长一段时间。
请提出任何其他可以评价这些更改的方法,以增加您对这些更改正确性的信心。