【问题标题】:Is it possible to add GroovyObject methods through a category?是否可以通过类别添加 GroovyObject 方法?
【发布时间】: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
}

到目前为止 invokeMethodgetPropertygetMetaClass 所以只有来自 GroovyObject 的其他两种方法:setMetaClasssetProperty 但由于这些方法的 getter 版本不起作用,我怀疑setter 版本也不起作用。所以我根本无法通过这种方式添加任何 GroovyObject 方法。

在另一个 SO 问题中:get vs getProperty in groovy 有一些关于 MOP 的讨论,唯一的答案指向“向元类添加方法而不是使用类别”解决方案。但我的问题不一样,真的可以使用类别添加invokeMethodmethodMissing吗?

那么通过类别添加GroovyObject 方法的正确方法是什么(如果有的话)?

【问题讨论】:

  • 引用声明不能添加 MOP(元对象协议)钩子方法。我不确定(因此不回答),但我怀疑invokeMethod 被视为澳门币。
  • 但是getProperty(另一种 GroovyObject 方法)也不起作用。也试过getMetaClass。所以它说“GroovyObject 方法”有点奇怪,但它们都不适合我。
  • 在那个问题中,唯一的答案只是将getProperty 添加到元类而不是使用类别,这是我试图避免的。如果不可能,那也没关系,但是 Groovy in Action 中的推荐让我认为必须有一种方法可以通过类别添加 GroovyObject 方法
  • 在 groovy 邮件列表中 Jochen Theodoru 表示通过类别添加 methodMissingpropertyMissing 应该可以工作

标签: groovy


【解决方案1】:

当前的 Groovy 2.4.x 无法执行此操作,但已为 2.5.0-rc-3、2.6.0-alpha-4、3.0.0-alpha-3 添加了此功能。因此,未来版本的 Groovy 将允许通过类别类重新定义 methodMissingpropertyMissing。此功能是在 2018 年 5 月提交 ad664b1 时添加的,并由 GROOVY-3867 跟踪

// since groovy 2.5.0-rc-3
class X{ def bar(){1}}
class XCat{ static bar(X x){2}}
class XCat2{ static bar(X x){3}}
class XCat3{ static methodMissing(X x, String name, args) {4}}
class XCat4{ static propertyMissing(X x, String name) {"works"}}    

def x = new X()

shouldFail(MissingPropertyException) {
  assert x.baz != "works" // accessing x.baz should throw MPE
}

use(XCat4) {
  assert x.baz == "works"
}

shouldFail(MissingPropertyException) {
  assert x.baz != "works" // accessing x.baz should throw MPE
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 2021-07-31
    相关资源
    最近更新 更多