【发布时间】:2018-05-21 08:23:37
【问题描述】:
在 Groovy in Action, 2nd Edition 于 2015 年发布的第 8.4.5 章中,他们说类别可用于添加 GroovyObject 方法:
类别方法名称可以很好地采用属性访问器的形式 (假装属性访问)、操作符方法和 GroovyObject 方法。不能通过类别类添加 MOP 挂钩方法。 这是 Groovy 2.4 的限制。该功能可能成为 在以后的版本中可用。
我解释为您可以添加getMetaClass()、setMetaClass(MetaClass)、getProperty(String)、setProperty(String, Object) 和invokeMethod(String, Object),但您不能添加methodMissing(String, Object) 或propertyMissing(String)
但是当我尝试通过一个类别添加 invokeMethod() 和 getProperty() 时,它没有任何效果:
class MyClass{}
a = new MyClass()
@Category(MyClass)
class MyCategory {
def missingMethod(String name, def args) { "missingMethod" } // GINA says no MOP hook method
def invokeMethod(String name, def args) { "invokeMethod" } // but GroovyObject method should be fine
def getProperty(String name) { "missingProperty" }
def getMyProperty() { "prop1" }
}
use(MyCategory) {
assert "missingMethod" == a.missingMethod('a', 'b') // methods are the
assert "invokeMethod" == a.invokeMethod('a', 'b')
assert "prop1" == a.myProperty
// but they are not in effect
// assert "missingMethod" == a.method1() // MissingMethodException
// assert "invokeMethod" == a.method2() // MssingMethodException
// assert "missingProperty" == a.property // MissingPropertyException
}
到目前为止 invokeMethod、getProperty 和 getMetaClass 所以只有来自 GroovyObject 的其他两种方法:setMetaClass 和 setProperty 但由于这些方法的 getter 版本不起作用,我怀疑setter 版本也不起作用。所以我根本无法通过这种方式添加任何 GroovyObject 方法。
在另一个 SO 问题中:get vs getProperty in groovy 有一些关于 MOP 的讨论,唯一的答案指向“向元类添加方法而不是使用类别”解决方案。但我的问题不一样,真的可以使用类别添加invokeMethod或methodMissing吗?
那么通过类别添加GroovyObject 方法的正确方法是什么(如果有的话)?
【问题讨论】:
-
引用声明不能添加 MOP(元对象协议)钩子方法。我不确定(因此不回答),但我怀疑
invokeMethod被视为澳门币。 -
但是
getProperty(另一种 GroovyObject 方法)也不起作用。也试过getMetaClass。所以它说“GroovyObject 方法”有点奇怪,但它们都不适合我。 -
在那个问题中,唯一的答案只是将
getProperty添加到元类而不是使用类别,这是我试图避免的。如果不可能,那也没关系,但是 Groovy in Action 中的推荐让我认为必须有一种方法可以通过类别添加 GroovyObject 方法 -
在 groovy 邮件列表中 Jochen Theodoru 表示通过类别添加
methodMissing和propertyMissing应该可以工作
标签: groovy