假设你有一个库在加载过程中会导致一些错误,如下所示
`
(ns broken-lib)
(} ; 这行将导致读取错误
`
然后,如果你require该库,即使发生了read错误,它也会被添加到{{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}}中删除。