假设你有一个库在加载时引发一些错误,如下所示
`
(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 中的错误后重新加载
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}} 中移除库。