Как заставить Clojure уважать переменную `* assert *`? - PullRequest
10 голосов
/ 02 февраля 2011

Я понял, что переменную 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

Так что теперь я не понимаю, что делать.Я в замешательстве.

Спасибо.

Ответы [ 2 ]

13 голосов
/ 02 февраля 2011

*assert* - это переменная времени компиляции, а не переменная времени выполнения. Он предназначен для использования с set! в качестве оператора верхнего уровня, а не с привязкой (конечно, если вы не вызовете eval внутри привязки).

4 голосов
/ 02 февраля 2011

assert - это макрос, определенный таким образом, что * assert * влияет на его поведение во время расширения.

если вы попробуете этот код, он будет работать должным образом:

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

и ваш пример с var-set также должен работать:

(var-set (var *assert*) false)
(assert false)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...