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

欢迎!有关如何使用本站,请参阅关于页面以获得更多信息。

+1
错误

`
=> (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: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)

原因
IllegalStateException a已经引用:#'foo/a,在命名空间:bar

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]) 警告:合并已引用:#'clojure.core/merge 在命名空间:try1.core,将被替换为:#'try1.core/merge 警告:* 已引用:#'clojure.core/* 在命名空间:try1.core,将被替换为:#'try1.core/* nil user=> (require '[try1.core :as c] ) nil user=> (require '[try1.core :as c] :reload) 警告:合并已引用:#'clojure.core/merge 在命名空间:try1.core,将被替换为:#'try1.core/merge 警告:* 已引用:#'clojure.core/* 在命名空间:try1.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形式被重新执行。

文档字符串暗示namespace可以用多次使用(将“ns”设置为name(未求值的)命名空间(如果需要则创建)),所以我会期待ns的多次调用是no-op

0

评论由:alexmiller发表

在CLJ-1578中重复。

0

评论者:mikera

这仍然困扰着我,并由于core.matrix的最新版本而引起破坏。我不知道这是否是一个回归问题,但在1.7.0-RC1中确实发生了。

我们能否为1.7获得一个修复补丁?由于这个问题而失败的代码,以及对用户代码进行重构的强制(我的用例是向clojure.core.matrix命名空间添加新变量,编译器错误在以前定义了相同名称的变量的用户代码中)真是太令人烦恼了。

0

评论者:mikera

关闭,因为我认为这个问题最好在相关问题上处理。

0

评论者:mikera

重新打开,因为CLJ-1578显然没有解决这个具体问题,它只涵盖了clojure.core中的vars。

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

0
_由 mikera_ 评论

复现过程

=> (ns foo)
nil
=> (def a 1)
#'foo/a
=> (ns bar (:require [foo :refer :all]))
nil
=> (def a 2)
编译器异常:java.lang IllegalStatException:a 已经在命名空间 bar 中引用:#'foo/a,编译:(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中评论的那样,我认为这不是bug,并且我认为应该拒绝这个工单。

覆盖非 clojure.core 的 vars 一直(至少从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

Hi Alex,这在问题发生时可以作为修复方案,但并不能解决未来用户代码破坏的问题,除非用户能准确预料到未来可能添加到"bar"中的符号数。这又似乎给用户带来了不合理的要求。

我想,我争辩的是,如果用户在自己的命名空间中定义了一个变量,他们愿意替换之前使用过的/refer-all'中任何具有类似名称的变量。

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

...