Groovy:使用metaClass向实例和类添加方法不起作用?

时间:2009-10-23 17:15:16

标签: groovy metaprogramming metaclass

请参阅下面的代码。在使用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'

3 个答案:

答案 0 :(得分:4)

  

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

该行:

parentDir.blech()
正如你所说,在将blech()添加到File后,

成功执行。但如果是这种情况那么为什么不会在它上面进行调用:

thisDir.blech()

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

相关问题