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

欢迎!请参阅关于页面以了解更多关于此的信息。

+4
Clojure
编辑

当前 clojure.core/*assert* 的默认值是 true

这给库的创建者和使用者带来一些影响。

作为一个库的创建者,你不能在各个地方添加断言来帮助你在开发/测试中,因为它会让大多数用户在生产中支付性能代价,因为他们将以启用 *asserts* 的形式运行。

作为一个库的使用者,因为你不知道哪些库在使用断言,你必须始终记得禁用它们以防止意外。

由于在 Clojure 中很难全球性地禁用它们,因为 assert 是一个检查 *assert* 的宏,变量的值需要在加载任何命名空间之前设置,这使得这种情况更加复杂。

相比之下,Java 默认禁用所有断言,因此库的创建者不必考虑这个问题,而消费者可以在开发时间通过提供 java -ea (启用断言) 明确启用它们。

由于我猜测更改 *assert* 的默认值可能因向下兼容性问题而变得复杂,所以或许可以添加一个像 Rust 中的 debug-assert,这默认不会启用。

在我看来,关键部分是拥有一个简单的检查指令,我们知道默认情况下不会影响性能,这样我们的代码库在测试和开发时的强化就不会与默认情况下的生产性能耦合。

其他两种选择是更好的默认值,一个是 false,另一个是 java.lang.Class#desiredAssertionStatus() 返回的值,这个值似乎根据是否提供 -ea 标志返回 true/false,默认也是 false。但是,由于大多数 Clojure 用户已经依赖于默认开启 assert,这可能不是一种选择。

by
我觉得添加类似 debug-assert 的功能非常有益,这样库的开发者可以在测试时选择启用(同时库的用户也可以选择启用测试),而应用程序的开发者则可以使用 assert 或选择在生成环境中禁用它们。
by
编辑了 by
我为 `debug-assert` 投票。我相信绝对需要有一种通用、可靠的方法,以便在不让你的人的任何生成环境中默认启用的情况下,将断言添加到库中。

一些检查在开发和应用测试中显然是可取的,但在生成环境中默认启用费用高昂;而另一些则可能在生成环境中是必要的,以避免潜在的数据损坏和复杂传播性失败。

库作者应该有权选择在哪里划这条线,这不应该是全部或没有的选择,而不应该在开发/测试过程中限制他们对事项的彻底验证,因为他们必须担心将过分的热心、费用高昂的检查发布给下游消费者。

当然,dev/test-only 和生产断言之间的区别对应用程序开发者来说也非常有用。

附言:Clojurians Slack 上的讨论线程
https://app.slack.com/client/T03RZGPFR/C03S1KBA2

编辑

我建议将标题更改为“将 `debug-assert` 添加为单独的默认禁用的高成本 dev/test-only 运作”来阐明这里所提议的内容。
by
我打算将https://docs.clojure.org/clojure.spec.alpha/assert 添加到对话中,因为这个默认是关闭的(在运行时,但可以在运行时打开以进行测试,也可以在编译时完全禁用)。

将此推荐为库方法的唯一问题是,您受Spec失败的摆布,因为没有自定义消息的选项,就像常规assert一样。
如果我的理解正确,你将只有调试断言在dev/test时间中进行断言。然后你会使用常规断言在生产环境中需要断言。

这开始有点像日志记录了。是否能增加类似日志级别的当前断言函数的“级别”呢?
我建议调试断言,只是为了不影响断言的向后兼容性。我认为,由于它们可以被禁用,目前的assert不应该用于任何生产相关的东西。我认为我们应该使用我们的正常(when-not something (throw ...))来检查代码中的重要内容。
debug-assert的整个目的就是拥有Java中assert的东西,一种您可以在dev中“滥用”以检查不变性,但您确信不会错误地进入生产并让您的代码用户承担性能代价。

所以我不认为这里有级别,而只是一个开发工具。

登录注册以回答此问题。

...