【问题标题】:Groovy: adding methods to instances and classes with metaClass doesn't work?Groovy:使用 metaClass 向实例和类添加方法不起作用?
【发布时间】:2010-12-09 13:04:38
【问题描述】:

请参阅下面的代码。在使用 metaClass 将方法添加到类之前创建的类的旧实例不应该理解该方法吗? 'PROBLEMATIC LINE' 注释下方的断言语句在我认为不应该执行时执行,因为旧的 parentDir 实例不应该理解 blech() 消息。

// derived from http://ssscripting.wordpress.com/2009/10/20/adding-methods-to-singular-objects-in-groovy/

// Adding a method to a single instance of a class

def thisDir = new File('.')

def parentDir = new File('..')

thisDir.metaClass.bla = { -> "bla: ${File.separator}" }

assert thisDir.bla() == "bla: ${File.separator}" : 'thisDir should understand how to respond to bla() message'

try {
    parentDir.bla()
    assert false : 'parentDir should NOT understand bla() message'
} catch (MissingMethodException mmex) {
    // do nothing : this is expected
}

// Adding a method to all instances of a class

File.metaClass.blech = { -> "blech: ${File.separator}" }

try {
    thisDir.blech()
    assert false : 'old instance thisDir should NOT understand blech() message'
} catch (MissingMethodException mmex) {
    // do nothing : this is expected
}

try {
    parentDir.blech()
    // PROBLEMATIC LINE BELOW - THE LINE IS EXECUTED WHEN
    // I THINK AN EXCEPTION SHOULD HAVE BEEN THROWN
    assert false : 'old instance parentDir should NOT understand blech() message'
} catch (MissingMethodException mmex) {
    // do nothing : this is expected
}

thisDir = new File('.')
parentDir = new File('..')

try {
    thisDir.bla()
    assert false : 'new instance thisDir should NOT understand bla() message'
} catch (MissingMethodException mmex) {
    // do nothing : this is expected
}

assert "blech: ${File.separator}" == thisDir.blech() : 'new instance thisDir should understand blech() message'
assert "blech: ${File.separator}" == parentDir.blech() : 'new instance parentDir should understand blech() message'

【问题讨论】:

    标签: groovy metaprogramming metaclass


    【解决方案1】:

    脚本以Caught: java.lang.AssertionError: old instance parentDir should NOT understand blech() message. Expression: false at x.run(x.groovy:35) 结束执行。您不希望blech 方法起作用吗?我不明白为什么不这样做,因为您将它添加到 File 元类,而不仅仅是对象的元类。

    【讨论】:

      【解决方案2】:

      行:

      parentDir.blech()
      

      如您所说,将 blech() 添加到 File 后成功执行。但如果是这样的话,为什么不上面的调用:

      thisDir.blech()
      

      work(不抛出它抛出的异常),因为它是 File 类的另一个实例,并且 blech() 已经添加到 File?两个调用都应该因 MissingMethodException 而失败,或者两者都应该工作。一个有效而另一个无效,这很愚蠢。

      【讨论】:

        【解决方案3】:

        旧的 parentDir 实例不应该 理解 blech() 消息

        metaclass 不是这样工作的。您显然来自基于原型的 OO 语言(JavaScript?)。 Groovy 不是基于原型的。对类的更改会影响该类的所有实例,包括在进行更改之前创建的实例。

        【讨论】:

          猜你喜欢
          • 2013-11-15
          • 2010-12-28
          • 2010-10-07
          • 2011-01-24
          • 2015-11-27
          • 1970-01-01
          • 2013-01-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多