如何让 Clojure 尊重 `*assert*` 变量?
我了解到 Clojure 的 *assert*
变量可用于关闭断言,但我所做的似乎都不起作用。
(defn foo [a]
{:pre [(pos? a)]}
(assert (even? a))
[a])
(binding [*assert* false]
(foo 1))
!! exception
(binding [*assert* false]
(foo -2))
!! exception
即使在定义时绑定 false
也有同样的问题:
(binding [*assert* false]
(defn bar [a]
{:pre [(pos? a)]}
(assert (even? a))
[a]))
(bar 1)
!! execption
然后甚至直接设置变量也不起作用。
*assert*
is true
(alter-var-root (var *assert*) not)
*assert*
is still true
所以
(var-set (var *assert*) false)
*assert*
is still true
现在我不明白该怎么办。我很困惑。
谢谢。
I was to understanding that Clojure's *assert*
variable could be used to turn off assertions, but nothing I do seems to works.
(defn foo [a]
{:pre [(pos? a)]}
(assert (even? a))
[a])
(binding [*assert* false]
(foo 1))
!! exception
(binding [*assert* false]
(foo -2))
!! exception
Even to binding false
when defining has same problems:
(binding [*assert* false]
(defn bar [a]
{:pre [(pos? a)]}
(assert (even? a))
[a]))
(bar 1)
!! execption
And then even to setting the variable direct does not working.
*assert*
is true
(alter-var-root (var *assert*) not)
*assert*
is still true
and
(var-set (var *assert*) false)
*assert*
is still true
So now I am not understanding what to do. I am confused.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
*assert*
是编译时变量,而不是运行时变量。它应该作为顶级语句与set!
一起使用,而不是与绑定一起使用(当然,除非您在绑定内部调用eval
)。*assert*
is a compile-time variable, not a runtime variable. It's meant to be used withset!
as a top-level statement, not with binding (of course unless you calleval
inside the binding).断言是以某种方式定义的宏,*assert* 会影响它在扩展时的行为。
如果您尝试此代码,它将按预期工作:
并且您的 var-set 示例也应该工作:
assert is macro defined in a way, that *assert* affects it's behavior at the expansion time.
if you try this code it will work as expected:
and your example with var-set should also work: