在Clojure中,* allow-unresolved-vars *做了什么?

时间:2014-08-14 23:20:22

标签: clojure

就像没有正式文件一样 http://clojuredocs.org/clojure_core/clojure.core/ 允许悬而未决-VARS

1 个答案:

答案 0 :(得分:1)

道歉 - 这不是一个完整的答案。我还没弄清楚它的一切。


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

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

并在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");
            }
        }

很明显,这里使用的是判断在遇到未解析的符号时是否应该立即抛出异常。

你可以像这样捣乱:

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) 

但我还没有想出一个用途,因为未解决的变量仍会导致错误 - 它们只是不同的错误。另外,在重新def时,我不理解这个警告,因为警告说它没有被声明为动态,而它看起来好像它在RT.java中被声明为动态。