11

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

だから今、私は何をすべきか理解していません。私は混乱しています。

ありがとうございました。

4

2 に答える 2

14

*assert*はコンパイル時の変数であり、実行時の変数ではありません。これは、バインディングではなく、トップレベルのステートメントとして使用することを目的としていset!ます(もちろんeval、バインディング内で呼び出さない限り)。

于 2011-02-02T14:28:16.487 に答える
4

assertは、ある意味でマクロ定義されており、*assert*は拡張時の動作に影響を与えます。

このコードを試してみると、期待どおりに機能します。

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

var-setを使用した例も機能するはずです。

(var-set (var *assert*) false)
(assert false)
于 2011-02-02T14:15:51.567 に答える