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: 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}} 中移除库。

7 个答案

0

由:alexmiller 评论:

这个补丁似乎与原因有些脱节 - 是否有方法可以在一开始就防止库被添加到 loaded-libs 中?

0

评论者:sohta

为了这样做,我认为我们需要撤销CLJ-1116。

0

由:alexmiller 评论:

我认为这种解决方案不好,所以将其移动到不完整状态。

0

评论者:sohta

您期待针对此问题有何种解决方案?

为了防止库在最初被添加到已加载库中,我认为ns宏需要知道它从哪里使用。当用于CLJ-1116的REPL时,它应立即添加ns,而当在文件中使用时,应推迟添加ns,直到整个文件在无错误的情况下加载完成。

0

评论者:gshayban

附上了与Shogo Ohta原始方法类似的方案。考虑到ns目前的工作方式,我认为这种方法是可行的。

为了支持在REPL中动态创建ns,CLJ-1116在ns宏内部写入加载的库,同时使加载库和加载库的一些逻辑变得不必要。这组补丁在加载失败时撤销副作用,并清理了一些死条件。

新行为:给定需要#{B, C}的ns A,如果B加载但C没有加载,则只有B将写入加载库,A和C将被撤销。这改善了加载体验,并解决了票证描述中所有令人讨厌的行为。

NB:'require'补丁包括
如果一个库在ns :require或:use中指定,加载该库的第一个结果必须是与库名称完全对应的ns。(直接调用load时没有这种限制,只有通过ns)我在测试套件中意外发现了一个使用下划线的库,其中加载的代码产生了带有连字符的命名空间。(也许c.c.specs应该比'简单符号?'为库指定更紧密的规范)

提交是分开的,并附有简短的说明性注释。

0

由:alexmiller 评论:

注意 - CLJ-2026可能由于对此更广泛问题的任何修复而变得不相关,并可以将其撤出。

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