2024 Clojure状态调查!分享你的想法。

欢迎!请参阅关于页面以获取更多关于如何使用此页面的信息。

+1
Clojure

假设你有一个库,在加载过程中会引发一些错误,如下所示

`
(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}} 中删除库。

7 个答案

0

评论者:alexmiller

此补丁似乎与原因有些脱离,有没有什么方法可以在一开始就防止库被添加到“已加载库”中呢?

0
by

评论者:sohta

要这样做,我认为我们需要回滚CLJ-1116。

0
by

评论者:alexmiller

我认为这种解决方案并不理想,因此将其移至“不完整”状态。

0
by

评论者:sohta

您希望对这个问题的解决方案有什么期望?

为了从一开始就防止库被添加到“已加载库”中,我认为ns宏需要知道它是从哪里被使用的。当用于CLJ-1116的REPL时,它应该立即添加ns,而在文件中使用时,应该延迟添加ns,直到整个文件加载无误完成。

0
by

评论者:gshayban

附加了一个类似于Shogo Ohta原始方法的方法。鉴于ns现在的运作方式,我认为这种方法是可行的。

为了在REPL中支持动态ns创建,CLJ-1116在ns宏内写入加载了loaded-libs,同时也取消了load-lib和load-libs中的一些逻辑。这一组补丁在加载失败时取消了副作用,并清理了一些无效的条件。

新行为:给定要求#{B, C}的ns A,如果B加载成功但C失败,则只有B将被写入loaded-libs,而A和C将取消。这改善了加载体验并修复了问题描述中的所有令人讨厌的行为。

注意:'require'补丁包括
如果一个库在ns :require或:use中被指定,则首次加载该库必须得到一个与库名称完全对应的新建ns。(在直接调用load时没有这样的限制,但只能通过ns)我在测试套件中发现了一个意外的库,其名称中包含下划线,加载代码的结果是一个包含短横线的命名空间。(也许cc.specs应为libs指定比'simple-symbol?'更严格的规范)

提交被分开,并附有简短的说明性评论。

0

评论者:alexmiller

注意 - 由于对更广泛问题进行的任何修复可能会使CLJ-2026变得无关紧要,因此它可以被移除。

0
参考:[https://clojure.atlassian.net/browse/CLJ-1406](https://clojure.atlassian.net/browse/CLJ-1406)(由sohta报告)
...