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

欢迎!请参阅关于页面以了解更多关于此网站如何运作的信息。

+7
Clojure

由于def形式的编译实现细节,其参数中的调用使用applyTo而不是直接使用invoke方法来评估。这迫使IFn的实现者即使在不需要的情况下也必须实现applyTo。

建议的补丁将InvokeExpr.eval更改为使用AFn.applyToHelper,以便在可能的情况下使用invoke而不是applyTo。

当前失败的代码示例(带有补丁将可行)

user=> (deftype x [] clojure.lang.IFn (invoke [_] 1)) user.x user=> (def a ((x.))) 抽象方法错误 clojure.lang.Compiler$InvokeExpr.eval (Compiler.java:3553)

我在使用Pathom(《https://github.com/wilkerlucio/pathom3》)时遇到了这个问题。Pathom定义了一个`Resolver` defrecord。解析器实现IFn,通常旨在像函数一样操作,例如用于调试目的,尽管通常不期望库用户直接调用它们,而是由库在查询运行期间通过`.invoke`方法调用。

我试图调试一个解析器,做了类似于`(def my-result (my-resolver my-args))`的事情,这会抛出此问题中描述的错误。在挖掘Clojure编译器代码了一段时间后,我怀疑是我用的`def`包裹函数调用是问题所在。

解析器最近实现了一个`.applyTo`方法(《https://github.com/wilkerlucio/pathom3/commit/0b40bc4aba7ff2d8e95dd4b120d04ef8d6c00cc7》),所以在Pathom中不再存在此问题,但我猜想这个问题的可能性更容易在较旧版本的Pathom或其他没有意识到需要实现`.applyTo`的IFn实现的库中出现。

1 个答案

0 投票
参考: https://clojure.atlassian.net/browse/CLJ-1715 (由 bronsa 报告)
...