Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Clojure respect `*assert*` variable?

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.

like image 528
Eli Schneider Avatar asked Feb 02 '11 12:02

Eli Schneider


2 Answers

*assert* is a compile-time variable, not a runtime variable. It's meant to be used with set! as a top-level statement, not with binding (of course unless you call eval inside the binding).

like image 157
cgrand Avatar answered Sep 18 '22 00:09

cgrand


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:

(binding [*assert* false]
   (eval '(assert false))
)

and your example with var-set should also work:

(var-set (var *assert*) false)
(assert false)
like image 44
aav Avatar answered Sep 18 '22 00:09

aav