我理解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
所以现在我不明白该怎么做。我很困惑。
谢谢。
答案 0 :(得分:13)
*assert*
是编译时变量,而不是运行时变量。它意味着与set!
一起用作顶级语句,而不是绑定(当然除非你在绑定中调用eval
。)
答案 1 :(得分:4)
断言是以某种方式定义的宏, * assert * 会影响它在扩展时的行为。
如果您尝试使用此代码,它将按预期工作:
(binding [*assert* false]
(eval '(assert false))
)
以及 var-set 的示例也应该有效:
(var-set (var *assert*) false)
(assert false)