请在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.))) 抛出AbstractMethodError clojure.lang.Compiler$InvokeExpr.eval (Compiler.java:3553)

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

我正在调试一个resolver并做了类似于`(def my-result (my-resolver my-args))`的事情,这抛出了本问题中描述的错误。我在Clojure编译器代码中挖掘了一段时间,才怀疑我在def函数调用中包裹功能调用的做法是罪魁祸首。

Resolvers最近实现了一个`.applyTo`(https://github.com/wilkerlucio/pathom3/commit/0b40bc4aba7ff2d8e95dd4b120d04ef8d6c00cc7,所以这个问题现在在Pathom中已经不再存在了。但我可以想象,在Pathom的旧版本或其他定义IFn实现但不意识到需要实现`.applyTo`的库中,这个问题仍然可能被遇到。

1 个回答

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