假设您有一个会导致加载过程中出现错误的库,例如以下
`
(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}}中删除库。