2011-02-02 20 views
10

Tenía que entender que la variable *assert* de Clojure se podía usar para desactivar las aserciones, pero nada de lo que hago parece funcionar.¿Cómo hacer que Clojure respete la variable `* assert *`?

(defn foo [a] 
    {:pre [(pos? a)]} 
    (assert (even? a)) 
    [a]) 

(binding [*assert* false] 
    (foo 1)) 
!! exception 

(binding [*assert* false] 
    (foo -2)) 
!! exception 

Incluso a la hora de definir la unión false tiene mismos problemas:

(binding [*assert* false] 
    (defn bar [a] 
    {:pre [(pos? a)]} 
    (assert (even? a)) 
    [a])) 

(bar 1) 
!! execption 

Y entonces, incluso a establecer la variable directa no trabajan.

*assert* 
is true 

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

y

(var-set (var *assert*) false) 
*assert* 
is still true 

Así que ahora yo no soy la comprensión de qué hacer. Estoy confundido.

Gracias.

Respuesta

13

*assert* es una variable en tiempo de compilación, no es una variable de tiempo de ejecución. Está destinado a ser utilizado con set! como una declaración de nivel superior, no con enlace (por supuesto a menos que llame al eval dentro del enlace).

4

assert se define macro de una manera, que * assert * afecta su comportamiento en el tiempo de expansión.

si se intenta el código que va a funcionar como se esperaba:

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

y su ejemplo, con var-set también debería funcionar:

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

Esto funciona. Podría apagar esto dinámicamente probando una variable de entorno. – Virmundi

Cuestiones relacionadas