Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
运行使用leiningen构建的uberjar时默认启用Clojure应用程序中的断言_Clojure - Fatal编程技术网

运行使用leiningen构建的uberjar时默认启用Clojure应用程序中的断言

运行使用leiningen构建的uberjar时默认启用Clojure应用程序中的断言,clojure,Clojure,当作为jar运行Clojure应用程序时,默认情况下是否应该启用断言 我们使用leiningen构建一个uberjar,然后java-jar…运行它,我刚刚发现*assert*是正确的 我找不到这个动态变量应该包含什么默认值,但我认为它应该是false(并且只在REPL开发环境中设置为true) 这与future一起导致了一个棘手的问题,前提断言错误导致future线程死亡,我们不知道发生了什么(因为我们只捕获了异常而不是可丢弃的) 我浏览了的源代码,但是我不知道*assert*var设置为tr

当作为jar运行Clojure应用程序时,默认情况下是否应该启用断言

我们使用leiningen构建一个uberjar,然后
java-jar…
运行它,我刚刚发现
*assert*
是正确的

我找不到这个动态变量应该包含什么默认值,但我认为它应该是false(并且只在REPL开发环境中设置为true)

这与
future
一起导致了一个棘手的问题,前提断言错误导致future线程死亡,我们不知道发生了什么(因为我们只捕获了
异常
而不是
可丢弃的

我浏览了的源代码,但是我不知道
*assert*
var设置为true的位置

我还在中找到了选项
:global vars
(在中提到)。 这看起来很合理,但我认为对于“生产”构建,我会自动得到
*assert*false


EDIT:我错过了
T
用来初始化
*assert*
变量的
RT.java
。但是,仍然很好奇为什么这是默认设置,以及关闭断言的建议方法(如果建议的话)。

从源代码看,
clojure.core/assert
是一个在编译时计算
*assert*
的宏:

(defmacro assert
  "Evaluates expr and throws an exception if it does not evaluate to
  logical true."
  {:added "1.0"}
  ([x]
     (when *assert*
       `(when-not ~x
          (throw (new AssertionError (str "Assert failed: " (pr-str '~x)))))))
  ([x message]
     (when *assert*
       `(when-not ~x
          (throw (new AssertionError (str "Assert failed: " ~message "\n" (pr-str '~x))))))))
这意味着
alter var root
binding
都不能更改
assert
的行为,因为它们在运行时运行,在
assert
已经评估
*assert*
之后。因此,
project.clj
中的
:global vars
选项:

  :global-vars {*warn-on-reflection* false
                *assert* false }
是唯一可行的解决方案,因为它是在宏展开之前进行评估的。使用此测试代码:

(dotest
  (spyxx *assert*)
  (assert false "Don't do that!")
  (println "past the assertion"))
我们得到的结果是:

----------------------------------
   Clojure 1.9.0    Java 10.0.1
----------------------------------

lein test tst.demo.core
*assert* => <#java.lang.Boolean false>
past the assertion

Ran 2 tests containing 0 assertions.
0 failures, 0 errors.
lein test  32.28s user 0.56s system 349% cpu 9.387 total
----------------------------------
Clojure 1.9.0 Java 10.0.1
----------------------------------
lein test tst.demo.core
*断言*=>
言过其实
运行了包含0个断言的2个测试。
0次失败,0次错误。
lein测试32.28s用户0.56s系统349%cpu 9.387总计

从源代码看,
clojure.core/assert
是一个宏,在编译时计算
*assert*

(defmacro assert
  "Evaluates expr and throws an exception if it does not evaluate to
  logical true."
  {:added "1.0"}
  ([x]
     (when *assert*
       `(when-not ~x
          (throw (new AssertionError (str "Assert failed: " (pr-str '~x)))))))
  ([x message]
     (when *assert*
       `(when-not ~x
          (throw (new AssertionError (str "Assert failed: " ~message "\n" (pr-str '~x))))))))
这意味着
alter var root
binding
都不能更改
assert
的行为,因为它们在运行时运行,在
assert
已经评估
*assert*
之后。因此,
project.clj
中的
:global vars
选项:

  :global-vars {*warn-on-reflection* false
                *assert* false }
是唯一可行的解决方案,因为它是在宏展开之前进行评估的。使用此测试代码:

(dotest
  (spyxx *assert*)
  (assert false "Don't do that!")
  (println "past the assertion"))
我们得到的结果是:

----------------------------------
   Clojure 1.9.0    Java 10.0.1
----------------------------------

lein test tst.demo.core
*assert* => <#java.lang.Boolean false>
past the assertion

Ran 2 tests containing 0 assertions.
0 failures, 0 errors.
lein test  32.28s user 0.56s system 349% cpu 9.387 total
----------------------------------
Clojure 1.9.0 Java 10.0.1
----------------------------------
lein test tst.demo.core
*断言*=>
言过其实
运行了包含0个断言的2个测试。
0次失败,0次错误。
lein测试32.28s用户0.56s系统349%cpu 9.387总计

Ok,我错过了
RT.java
中用来初始化
*assert*
变量的
T
小东西(布尔值true)。但是,仍然很好奇为什么这是默认值,以及关闭断言的建议方法(如果建议的话)。好吧,我错过了用于初始化
*assert*
变量的
RT.java
中的
T
小东西(布尔真)。但是,仍然很好奇为什么这是默认设置,以及关闭断言的建议方法是什么(如果建议的话)。