Mat*_*ick 1

抱歉——这不是一个完整的答案。我还没弄清楚这一切。


*allow-unresolved-vars*在RT.java中定义:

final static Var ALLOW_UNRESOLVED_VARS = Var.intern(CLOJURE_NS, Symbol.intern("*allow-unresolved-vars*"), F).setDynamic();
Run Code Online (Sandbox Code Playgroud)

并在Compiler.java中使用:

    if(o == null)
        {
        if(RT.booleanCast(RT.ALLOW_UNRESOLVED_VARS.deref()))
            {
            return sym;
            }
        else
            {
            throw Util.runtimeException("Unable to resolve symbol: " + sym + " in this context");
            }
        }
Run Code Online (Sandbox Code Playgroud)

很明显,它在这里的用途是决定当遇到未解析的符号时是否应该立即抛出异常。

你可以像这样搞乱它:

myns.core=> (ns clojure.core)
nil

clojure.core=> oops!
CompilerException java.lang.RuntimeException: Unable to resolve symbol: oops! in this context, compiling:(/tmp/form-init1596111142512149454.clj:1:884) 

clojure.core=> (defn q [] (oops!))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: oops! in this context, compiling:(/tmp/form-init1596111142512149454.clj:1:12) 

clojure.core=> (def *allow-unresolved-vars* true)
Warning: *allow-unresolved-vars* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *allow-unresolved-vars* or change the name. (/tmp/form-init1596111142512149454.clj:1)
#'clojure.core/*allow-unresolved-vars*

clojure.core=> oops!
IllegalArgumentException UnresolvedVarExpr cannot be evalled  clojure.lang.Compiler$UnresolvedVarExpr.eval (Compiler.java:1771)
clojure.core=> 

clojure.core=> (defn q [] (oops!))
CompilerException java.lang.VerifyError: (class: clojure/core$q, method: invoke signature: ()Ljava/lang/Object;) Unable to pop operand off an empty stack, compiling:(form-init1596111142512149454.clj:1:1) 
Run Code Online (Sandbox Code Playgroud)

但我还没有找到用途,因为未解析的变量仍然会导致错误——它们只是不同的错误。另外,我不明白重新编译def它时的警告,因为警告说它没有声明为动态的,而在我看来它好像在 RT.java 中声明为动态的。