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

欢迎!有关此功能的更多信息,请参阅 关于 页面。

+1
错误

`
=> (ns foo)
nil
=> (def a 1)

'foo/a

=> (ns bar (:require [foo :refer :all]))
nil
=> (def a 2)
编译器异常 java.lang.IllegalStateException: a 已经在命名空间 bar 中引用: #'foo/a, 编译于:(NO_SOURCE_PATH:4:1)

clojure.lang.Compiler.analyzeSeq (Compiler.java:6745)
clojure.lang.Compiler.analyze (Compiler.java:6529)
clojure.lang.Compiler.analyze (Compiler.java:6490)
clojure.lang.Compiler.eval (Compiler.java:6801)
clojure.lang.Compiler.eval (Compiler.java:6760)
clojure.core/eval (core.clj:3079)
clojure.main/repl/read-eval-print--7095/fn--7098 (main.clj:240)
clojure.main/repl/read-eval-print--7095 (main.clj:240)
clojure.main/repl/fn--7104 (main.clj:258)
clojure.main/repl (main.clj:258)
clojure.main/repl-opt (main.clj:324)
clojure.main/main (main.clj:422)

原因
java.lang(IllegalStateException) a 已经在命名空间 bar 中引用: #'foo/a

clojure.lang.Namespace.warnOrFailOnReplace (Namespace.java:88)
clojure.lang.Namespace.intern (Namespace.java:72)
clojure.lang.Compiler$DefExpr$Parser.parse (Compiler.java:534)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6738)
clojure.lang.Compiler.analyze (Compiler.java:6529)

`

我期望(在最坏的情况下)会有一个类似于初始命名空间加载的警告,而不是在这里抛出异常。

22 个回答

0

评论由:alexmiller 提出

您能否为此问题编写一个更好的可重现测试用例,而不依赖于 core.matrix?也请包含当 (pst **e) 发生时的情况。

0

评论由:jafingerhut 提出

我曾尝试过尽可能小的 Leiningen 项目,以引起关于重新定义的警告,以查看是否能引发异常。使用 'lein new try1' 创建基本项目架构,然后编辑 src/try1/core.clj 以包含以下函数定义:

`
(defn merge
"此 merge 定义的合并替换了 clojure.core/merge";
[x y]
(- x y))

(defn
[x y]
(
x y))
`

然后使用 'lein repl' 启动 REPL,我看到这种行为

user=> (require '[try1.core :as c]) 警告:merge 已在 try1.core 命名空间中引用:#'clojure.core/merge,正在替换为:#'try1.core/merge 警告:* 已在 try1.core 命名空间中引用:#'clojure.core/*,正在替换为:#'try1.core/* nil user=> (require '[try1.core :as c] ) nil user=> (require '[try1.core :as c] :reload) 警告:merge 已在 try1.core 命名空间中引用:#'clojure.core/merge,正在替换为:#'try1.core/merge 警告:* 已在 try1.core 命名空间中引用:#'clojure.core/*,正在替换为:#'try1.core/* nil

这看起来就像我预期的行为,我没有看到 Mike 报告的异常。

似乎在 Counterclockwise 中,Ctrl+Alt+L 做的事与 (require ... :reload) 不同,或者 Mike 的命名空间有其他不同之处,除了在 clojure.core 中重定义名称之外,这也导致了问题。

0

评论由:alexmiller 提出

暂时标记为 NR - 很高兴看到它可以重新打开,并带有易于复现的测试用例。

0

由 mikera 发表的评论

复现方法

(ns op)
(defn (link: a b) (clojure.core/ a b)) ;; 给出警告
(ns use-op (:require (link: op :refer :all))) ;; 给出警告
(ns use-op (:require (link: op :refer :all))) ;; 给出错误!

我相信 Counterclockwise 只是用 CTRL-Alt+L 重新加载了命名空间,这导致了 ns 表达式的重新执行。

文档字符串隐含了 ns 可以多次使用 ("将 ns 设置为由名称命名的命名空间,如果有必要则创建它"),所以我对多次调用 ns 应该是一个无操作表示。

0

评论由:alexmiller 提出

Duped in CLJ-1578.

0

由 mikera 发表的评论

这仍然在影响着我,并且导致 core.matrix 最新版本出现崩溃。我不知道这是回归还是什么,但它确实在 1.7.0-RC1 中发生。

我们能否在 1.7 中得到修复?代码因为这个问题而失败,并且要强制重构用户代码真的很烦人(我的用例是向 clojure.core.matrix 命名空间添加一个新的变量,在之前定义了相同名称的变量的用户代码中发生编译错误)。

0

由 mikera 发表的评论

关闭此条目,我认为这应该在相关的问题中处理

0

由 mikera 发表的评论

重新开放,因为 CLJ-1578 似乎没有解决这个具体问题,它只覆盖了 clojure.core 中的变量。

我仍然希望看到这个问题在所有命名空间中得到修复,而不仅仅是 clojure.core。

0
_由 mikera_ 发布的评论

复制

=> (ns foo)
nil
=> (def a 1)
#'foo/a
=> (ns bar (:require [foo :refer :all]))
nil
=> (def a 2)
编译器异常 java.lang.IllegalStateException: a 已经引用了: #'foo/a 在命名空间: bar,编译中:(NO_SOURCE_PATH:1:1)
=> *clojure-version*
{:major 1, :minor 7, :incremental 0, :qualifier "RC1"}

堆栈跟踪

编译器异常 java.lang.RuntimeException: 在此上下文中无法解决符号: pst,编译中:(NO_SOURCE_PATH:1:1)
    clojure.lang.Compiler.analyze (Compiler.java:6543)
    clojure.lang.Compiler.analyze (Compiler.java:6485)
    clojure.lang.Compiler$InvokeExpr.parse (Compiler.java:3737)
    clojure.lang.Compiler.analyzeSeq (Compiler.java:6735)
    clojure.lang.Compiler.analyze (Compiler.java:6524)
    clojure.lang.Compiler.analyze (Compiler.java:6485)
    clojure.lang.Compiler$BodyExpr$Parser.parse (Compiler.java:5861)
    clojure.lang.Compiler$FnMethod.parse (Compiler.java:5296)
    clojure.lang.Compiler$FnExpr.parse (Compiler.java:3925)
    clojure.lang.Compiler.analyzeSeq (Compiler.java:6731)
    clojure.lang.Compiler.analyze (Compiler.java:6524)
    clojure.lang.Compiler.eval (Compiler.java:6789)
原因
RuntimeException 无法在此上下文中解决符号: pst
    clojure.lang.Util.runtimeException (Util.java:221)
    clojure.lang.Compiler.resolveIn (Compiler.java:7029)
    clojure.lang.Compiler.resolve (Compiler.java:6973)
    clojure.lang.Compiler.analyzeSymbol (Compiler.java:6934)
    clojure.lang.Compiler.analyze (Compiler.java:6506)
    clojure.lang.Compiler.analyze (Compiler.java:6485)

0

评论由: bronsa 发布

正如我在 CLJ-1578 中评论的那样,我不认为这是一个错误,我认为应该拒绝这个工单。

覆盖非 clojure.core 变量一直(至少从 1.2 版本起)会导致抛出异常。

0

评论由: bronsa 发布

Mike,可能在clojure-dev ml上提出这个问题,以获得一些意见是个不错的想法?

0

由 mikera 发表的评论

如果您愿意,将其重新分类为一个特性请求。

我仍然认为这是一个缺陷,因为我期望:refer :all能正常工作。

无论如何,这个问题都不断破坏我领域(数据科学/探索性统计/数据管理)中的用户代码。使用/引用所有的能力对于设置方便的探索工作命名空间非常有用,所以我不会接受迫使用户明确要求使用每个变量(如CLJ-1578中Nicola建议的)是一种实际的解决方案。

这也让我在REPL中工作并重新加载命名空间时遇到了问题。

如果Clojure核心团队真的希望保持这种令人讨厌的行为,我们至少应有一种方法可以在库级别关闭它?也许可以为clojure.core.matrix命名空间添加一些命名空间元数据来停止这种情况触发?

0

评论由: bronsa 发布

Mike,这只是我的个人观点, я не являюсь частью ядра команды, и я не представляю их, поэтому я предложил написать вам в clojure-dev ml.

为了澄清,您报告的问题不能在重新加载命名空间时出现,因为异常是在定义重新发生时抛出的。

0

评论由:alexmiller 提出

您可以使用:exclude来做这件事。

(ns bar (:require [foo :refer :all :exclude [a]]))

0

由 mikera 发表的评论

Hello Alex,当问题出现时,这是一个修复问题的方式,但它并不解决未来的用户代码破坏问题,除非用户准确地预见到未来会被添加到“bar”中的符号。这再次似乎给用户带来了不合理的要求。

我想我争论的是,如果用户在自己的命名空间中定义了一个变量,那么他们愿意替换先前提到的任何有相同名称的命名空间中的变量。

如果用户真正担心意外覆盖问题,我会对一种类似 warn-on-reflectionwarn-on-replace 很感兴趣。我之前在 CLJ-1257 中提出了类似的想法,甚至编写了一个补丁,以这种方式解决了整个问题。我们能否在 1.7 中得到这个补丁或类似的东西?

...