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

欢迎!请参阅关于页面,了解更多关于这个工作的信息。

+7
Clojure

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

提出的补丁将InvokeExpr.eval改为使用AFn.applyToHelper,因此当可能时,将使用invoke而不是applyTo。

目前失败代码的示例,Patch后会工作

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。解算器实现IFn,通常旨在直接作为函数调用,例如用于调试目的,尽管通常不期望库用户直接调用,而是由库在通过`.invoke`方法执行查询时进行调用。

我试图调试我的一个解算器,执行了类似`(def my-result (my-resolver my-args))`的操作,这引起了这个问题中描述的错误。在翻阅Clojure编译器代码一段时间后,我才怀疑我包裹函数调用的`def`是我的问题所在。

解算器最近增加了一个`.applyTo`的实现(https://github.com/wilkerlucio/pathom3/commit/0b40bc4aba7ff2d8e95dd4b120d04ef8d6c00cc7),因此在Pathom中不再存在此问题,但我认为在Pathom的旧版本或其他定义IFn实现而没有意识到需要实现`.applyTo`的库中,这个问题很容易再次发生。

1 个答案

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