2024 年 Clojure 状态调查!中分享您的想法。

欢迎!有关如何工作的更多信息,请参阅关于页面。

+2
错误

https://github.com/clojure/clojure/blob/653b8465845a78ef7543e0a250078eea2d56b659/src/jvm/clojure/lang/Namespace.java#L224-L225 中,未在异常信息中包含 ns 参数。

这阻碍了调试性,特别是在 .addAlias 调用不是来自有意的别名映射,而是由于重新评估命名空间(这是如 https://github.com/jonase/eastwood 之类的工具使用的抽象语法树构建策略)的情况下。

你考虑过改进消息吗?

1 答案

+1

示例?建议的变更?

期望的示例消息

`别名 __ (旨在引用 __) 在命名空间 __ 中已存在,别名 __`

其中 `(旨在引用 __)` 是新添加的部分。

建议的更改

使用此 Java 方法的 `ns` 参数作为消息的一部分。

其实用性在于它允许区分两种情况

* 期望的别名简单地与一个现有的、不同名称的条目重叠
* 两个 java.lang.Namespace 对象正在比较,代表相同的命名空间但不相等(`.equals` 比较),这是由于代码重新加载不正确(代码重新加载问题, `eval` 问题)
我认为这是一个第一例的例子

user=> (require 'clojure.set)
null
user=> (require 'clojure.string)
null
user=> (alias 's 'clojure.set)
null
user=> (alias 's 'clojure.string)
执行错误(IllegalStateException)在用户/eval151 (REPL:1)。
别名 s 在命名空间 user 中已存在,别名 clojure.set

对我来说这似乎很清楚,我不确定提及尝试的别名命名空间是否有帮助。你能解释一下你是如何进入第二种情况的吗?
你的例子正确描述了我所说的 "[...]" 与现有的、不同名称的条目重叠。

关于第二种情况,反映在 https://github.com/clojure/tools.namespace/tree/e5a9a2abc5360cef57d6f97908b1ec9d5322597a#warnings-for-aliases 中,其中存在两个相互竞争的 "com.example.foo" clojure.lang.Namespace 对象。
symlink
在那个情况下问题似乎也很清楚。
symlink
这(在某种程度上)是清楚的,因为这是一个直接、细粒度的用户交互。我说“在某种程度上”,因为人们并不一定知道什么是clojure.lang.Namespace对象,或者这些对象中可能有两个存在于同一个文件中。

这并不总是这种情况:Eastwood等工具会在指定项目的顶层形式上执行`eval`操作(不那么直接,不那么细粒度)。

因此,人们可能会遇到这个错误,同时怀疑问题是否由加载代码的顺序不正确造成的,或者Eastwood实际上在放置重叠别名。

因此,Eastwood的问题调试确实因这些不完整的错误信息而受到阻碍。
by
所以,这应该是你最初的问题,实际上存在的问题,而不是一个深入到实现层面上的建议方案。

东wood导致问题的具体事件序列是什么?Eastwood可以避免或检测这个场景吗?
by
我理解你想要指出的问题,但同时,这是一个非常常见的错误。这种错误在某个时刻可能会很常见,看到有人对其进行提问,等等。

除了Eastwood之外的其他工具也使用类似策略来执行`eval`代码(参见https://github.com/clojure-emacs/refactor-nrepl/tree/71e057c413933e25f2ae5921f6aad4a262ae90ce "launch-missiles"警告),因此,栈中的工具越多,越容易遇到这些错误,拥有完整的调试信息就越有用,这允许一个人排除错误假设。

就说这些,我可以在东wood中深入挖掘并找到修复方案(目前只是一个内部的分支):https://github.com/nedap/eastwood .

所以,这个ask.clojure.org的请求并不是为了获得我已经拥有的工具特定修复;它是一个请求,要求在调试类似问题(在不同的时间或由不同的人)时避免类似的痛苦。
by
如果这感觉我过于固执,但我是试图系统地解决这个问题(“这是发生的事情,这是我缺少必要信息的地方”),而不是从一开始就以解决方案(“只是改变一些代码”)为起点,以确保我们正在做正确的事情。

在这一点上,您还没有描述一个详细、可重复的场景,以复制实际遇到的问题。没有这一点,我们就没有办法 a) 考虑其他可能的解决方案或 b) 测试和验证特定的更改是否解决了问题。您声称该问题既普遍又经常被报告。如果是这样,应该很容易指向其中一个这些讨论或描述该场景,这正是我所需要的。

我尝试使用 tools.namespace 工具来重现这种错误,但唯一成功的方法是在 repl 中使用 require,在这一步中更改该消息不会给我任何额外的信息

    user=> (require '[foo :as bar])
    执行错误(IllegalStateException) user/eval1664 (REPL:1).
    别名 bar 已在用户命名空间中存在,别名 foo

请注意,在 Clojure 1.10.0+ 中,这里没有打印堆栈的顶部行,因此您看不到“Namespace”(tools.namespace 中的示例是较旧版本)。说“别名 bar(原本打算引用 foo)已在用户命名空间中存在,别名 foo”在理解或解决该问题上提供的信息不多,对吗?
...