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

7 答案

0

评论由: alexmiller 制作

这个补丁似乎与原因有些脱节 - 是否有方法从一开始就阻止将该库添加到 loaded-libs 中?

0

评论由:sohta发表

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

0

评论由: alexmiller 制作

我认为这个解决方案不是很理想,因此将其改为不完整。

0

评论由:sohta发表

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

为了从一开始就防止将库添加到 loaded-libs 中,我认为 ns 宏需要知道它在哪里被使用。当在 REPL 中使用 CLJ-1116 时,它应立即添加 ns,而在文件内部使用时,应推迟添加 ns,直到整个文件不存在错误时完成加载。

0

评论由: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)我在测试套件中发现了一个意外的库,其名称中有下划线,而加载的代码则产生了带有短横线的命名空间。也许c.c.specs应该对库的指定比'simple-symbol?'更严格)

提交是分开的,附有简短的解释说明。

0

评论由: alexmiller 制作

注意 - CLJ-2026可能因为修复这个更广泛的问题而变得不相关,然后可以被移除。

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