假设你有一个库,在加载过程中会引发一些错误,如下所示
`
(ns broken-lib)
(} ; 这行将引发读取器错误
`
然后,如果你使用 {{require}} 加载这个库,它会因为读取器错误而被添加到 {{loaded-libs}} 中,但在随后会静默地成功执行 {{require}}。
user=> (contains? (loaded-libs) 'broken-lib) false user=> (require 'broken-lib) CompilerException:java.lang.RuntimeException:未匹配的分隔符:},编译:(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)
编译器异常:java.lang.RuntimeException:未匹配的分隔符:},编译:(broken_lib.clj:3:3)
user=> (require 'broken-lib.core :reload)
编译器异常:java.lang.Exception:未找到命名空间 'broken-lib',编译:(broken_lib/core.clj:1:1)
user=> (require 'broken-lib.core :reload) ;; 修复 broken-lib 中的错误后重新加载
编译器异常:java.lang.Exception:未找到命名空间 'broken-lib',编译:(broken_lib/core.clj:1:1)
user=>
`
原因
CLJ-1116的补丁使 {{ns}} 宏即使在加载过程中出现错误也会无视地将正在定义的库添加到 {{loaded-libs}} 中。
方法
修改 {{clojure.core/load-lib}} 以在发生错误时从 {{loaded-libs}} 中删除库。