如何使Clojure尊重`*assert*`变量?

如何使Clojure尊重`*assert*`变量?,clojure,assertions,Clojure,Assertions,我理解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 [*ass

我理解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
甚至设置变量direct也不起作用

*assert*
is true

(alter-var-root (var *assert*) not)
*assert*
is still true

所以现在我不知道该怎么办。我很困惑


谢谢。

assert是宏定义的,它在某种程度上影响扩展时的行为

如果您尝试此代码,它将按预期工作:

(binding [*assert* false]
   (eval '(assert false))
)
您的var set示例也应该适用:

(var-set (var *assert*) false)
(assert false)

*assert*
是编译时变量,而不是运行时变量。它应该与
set一起使用
作为顶级语句,而不是绑定(当然,除非您在绑定内部调用
eval

这确实有效。您可以通过测试环境变量来动态关闭此功能。
(var-set (var *assert*) false)
(assert false)