Groovy 将方法添加到闭包

Groovy 将方法添加到闭包,groovy,Groovy,我已经在闭包的元类中添加了一个方法,但是我似乎无法获得该方法正在被调用的实例的引用。在本例中,delegate设置为脚本实例,而不是我正在调用的fixedPoint闭包: Closure.metaClass.fixedPoint = { while (it != (it = delegate.call(it))) {} it } def f = { Math.round(it / 2.0) } println f.fixedPoint(9) 给予 捕获:groovy.lang.

我已经在
闭包
元类
中添加了一个方法,但是我似乎无法获得该方法正在被调用的实例的引用。在本例中,
delegate
设置为脚本实例,而不是我正在调用的
fixedPoint
闭包:

Closure.metaClass.fixedPoint = {
    while (it != (it = delegate.call(it))) {}
    it
}
def f = { Math.round(it / 2.0) }
println f.fixedPoint(9)
给予

捕获:groovy.lang.MissingMethodException:没有方法的签名:test.call()适用于参数类型:(java.lang.Integer)值:[9]
这里我做错了什么?

问题是
闭包.metaclass
{->}.metaclass
是不同的实例

println (Closure.metaClass)
println ({ -> }.metaClass)
收益率:

org.codehaus.groovy.runtime.HandleMetaClass@12f5f0d
org.codehaus.groovy.runtime.metaclass.ClosureMetaClass@192d8d6

问题是
Closure.metaclass
{->}.metaclass
是不同的实例

println (Closure.metaClass)
println ({ -> }.metaClass)
收益率:

org.codehaus.groovy.runtime.HandleMetaClass@12f5f0d
org.codehaus.groovy.runtime.metaclass.ClosureMetaClass@192d8d6
说明: 如果执行
Closure.metaClass.fixedPoint=…
,则类闭包将获得一个新的元类,即ExpandoMetaClass。在下一步中,将添加该方法。现在闭包的默认元类是ClosureMetClass,它既不允许添加方法,也不太关心其他元类。当您执行
def={Math.round(it/2.0)}
时,您实际上创建了一个新类(及其实例)。它扩展了闭包,但不是闭包本身。默认情况下,这个类将ClosureMetaClass作为元类,完全忽略您对闭包的元类所做的操作

解决方案: 您必须强制使用ExpandoMetaClass,因此代码的第一行(在分配f之前)应该是
ExpandoMetaClass.enableGlobally()

至少对我来说,这段代码毫无例外地运行

旁注: 存储在元类中用于形成方法的闭包通常是您提供的闭包的克隆。然后,元类将在副本上设置委托。例如,通过
println f.@delegate
检查f的委托将不会显示结果。

说明: 如果执行
Closure.metaClass.fixedPoint=…
,则类闭包将获得一个新的元类,即ExpandoMetaClass。在下一步中,将添加该方法。现在闭包的默认元类是ClosureMetClass,它既不允许添加方法,也不太关心其他元类。当您执行
def={Math.round(it/2.0)}
时,您实际上创建了一个新类(及其实例)。它扩展了闭包,但不是闭包本身。默认情况下,这个类将ClosureMetaClass作为元类,完全忽略您对闭包的元类所做的操作

解决方案: 您必须强制使用ExpandoMetaClass,因此代码的第一行(在分配f之前)应该是
ExpandoMetaClass.enableGlobally()

至少对我来说,这段代码毫无例外地运行

旁注:
存储在元类中用于形成方法的闭包通常是您提供的闭包的克隆。然后,元类将在副本上设置委托。例如,
println f.@delegate
检查f的委托时不会显示结果。

感谢您的回复。我现在的问题是:为什么?如何修复代码段
({->}).metaClass.fixedPoint=…
不起作用:
捕获:groovy.lang.MissingPropertyException:没有这样的属性:类的fixedPoint:org.codehaus.groovy.runtime.metaClass.ClosureMetaClass
我怀疑原因之一是
ClosureMetaClass
不是
ExpandoMetaClass
的子类。也许可以通过DirectAPI将元方法添加到元类中,但我还没有尝试。谢谢您的回复。我现在的问题是:为什么?如何修复代码段
({->}).metaClass.fixedPoint=…
不起作用:
捕获:groovy.lang.MissingPropertyException:没有这样的属性:类的fixedPoint:org.codehaus.groovy.runtime.metaClass.ClosureMetaClass
我怀疑原因之一是
ClosureMetaClass
不是
ExpandoMetaClass
的子类。可能可以通过DirectAPI将元方法添加到元类中,但我还没有尝试。