假设您有一个在加载过程中引起一些错误的库,如下所示
`
(ns broken-lib)
(} ; 这行代码将引起阅读器错误
`
然后,如果您尝试使用 {{require}} 加载这个库,即使在读取器错误发生的情况下,它也会被添加到 {{loaded-libs}} 中,{{require}} 后面的操作将成功地静默执行。
user=> (contains? (loaded-libs) 'broken-lib) false user=> (require 'broken-lib) CompilerException java.lang.RuntimeException: Unmatched delimiter: }, compiling:(broken_lib.clj:3:3) user=> (contains? (loaded-libs) 'broken-lib) true user=> (require 'broken-lib) nil user=>
如果您还有另一个需要损坏库的命名空间(例如,这里的 {{broken-lib.core}}),则问题会更糟
(ns broken-lib.core (:require [broken-lib :as lib]))
虽然您第一次加载依赖的命名空间时会得到实际的错误,但之后您会发现在尝试重新加载它时每次都会抛出一个错误的编译器异常。即使在您实际上修复了引起原始错误的代码之后,这种状况也将持续存在。
`
user=> (require 'broken-lib.core)
CompilerException java.lang.RuntimeException: Unmatched delimiter: }, compiling:(broken_lib.clj:3:3)
user=> (require 'broken-lib.core :reload)
CompilerException java.lang.Exception: namespace 'broken-lib' not found, compiling:(broken_lib/core.clj:1:1)
user=> (require 'broken-lib.core :reload) ;; 修复后重新加载 broken-lib 中的 bug
CompilerException java.lang.Exception: namespace 'broken-lib' not found, compiling:(broken_lib/core.clj:1:1)
user=>
`
原因
CLJ-1116 的补丁使得 {{ns}} 宏盲目地将正在定义的库添加到 {{loaded-libs}} 中,即使在加载过程中发生错误也不例外。
方法
修改 {{clojure.core/load-lib}},使其在错误发生时从 {{loaded-libs}} 中移除库。