以下のコードを参照してください。metaClass を使用してメソッドがクラスに追加される前に作成されたクラスの古いインスタンスは、メソッドを理解するべきではありませんか? 「PROBLEMATIC LINE」コメントの下の assert ステートメントは、古い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'