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 所使用的 AST 建造策略)时。

您是否考虑过改进消息?

1 个答案

+1

示例?建议的更改?

希望的消息示例

`在命名空间 __ 中,别名 __ (期望引用到 __) 已存在,别称 __`

其中 `(期望引用到 __)` 是新的一部分。

建议的更改

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

其实际用途在于允许区分两种情况

* 目标别名与现有的、名称不同的条目重叠
* 正在比较两个代表相同命名空间但不相等的 `java.lang.Namespace` 对象(由于代码重新加载错误导致),这 Cod reloading issues, `eval` issues)
我猜测这是一个第一类情况的例子

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

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

至于另一个情况,反映在https://github.com/clojure/tools.namespace/tree/e5a9a2abc5360cef57d6f97908b1ec9d5322597a#warnings-for-aliases 中,其中有两个竞争性的“com.example.foo” clojure.lang.Namespace对象。
在那种情况下,问题似乎也很明确。
作者
因为这是一个直接、细致的用户交互,所以(多少有点)清晰。我说“多少有点”,因为人们并不一定知道clojure.lang.Namespace对象是什么,或者相同的文件可能存在两个这样的对象。

并不总是这样:Eastwood这样的工具将会在一个给定项目顶级形式的`eval`上执行(不如直接,不如细致)。

因此,有可能会遇到这个错误,然后留下疑问,是否是因为代码加载顺序不正确,或者Eastwood实际上放置了重叠的别名。

因此,调试Eastwood问题时,这些不完整的错误消息确实妨碍了调试。
作者
所以,这应该是你最初的问题,实际问题,而不是实施中的一个解决方案。

Eastwood导致问题的活动顺序是什么?Eastwood能否避免或检测这种情况?
作者
我理解你的意图,但与此同时,这是一个并不罕见的问题。这在一定程度上是常见的,人们在某个时刻会遇到它,询问相关问题,等等。

除了Eastwood之外的工具也使用类似策略进行代码`eval` (参看https://github.com/clojure-emacs/refactor-nrepl/tree/71e057c413933e25f2ae5921f6aad4a262ae90ce “launch-missiles”警告)。所以一个人的工具堆栈中包含的工具越多,则更容易遇到这些错误,并且拥有完整的调试信息就越有用,允许人们排除错误假设。

FWIW,我可以深入了解Eastwood,并找到修复(目前仅作为一个内部分支):https://github.com/nedap/eastwood

因此,这个ask.clojure.org请求不是为了得到我已经拥有的工具特定的修复;而是一个请求,避免在调试类似问题时(在别的时间,或由不同的人)遇到类似的痛苦。
如果这感觉像我固执的话,但我正尝试系统性地处理这个问题(“这是发生的事情,这是我缺少必要信息的地方”)而不是从解决方案开始(“只是更改一些代码”)以确保我们正在做正确的事情。

目前,您尚未描述一个详细、可重复的场景来重现实际的问题。没有这个,我们就无法考虑其他可能的解决方案或测试并验证某个特定的更改是否解决了问题。您声称这个问题既常见又被广泛报道。如果是这样,应该很容易指出这些讨论之一或描述场景,我需要的就是这样。

我尝试使用 tools.namespace 工具来重现这种错误,唯一的方法是使用 repl 中的 require,在那里更改此消息不会给我提供任何额外的信息。

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

注意,在 Clojure 1.10.0+ 中,这里不打印堆栈的最顶层,因此您看不到 "Namespace"(工具命名空间说明中的例子比较老)。说“别名 bar(初衷是为了指代 foo)在用户命名空间中已经存在,别名 foo”既没有提供更多的信息来理解问题,也没有解决问题,对吗?
...