Groovy 1.8.6 では、次のようなことをしようとしていました。
class Greeter {
def sayHello() {
this.metaClass.greeting = { System.out.println "Hello!" }
greeting()
}
}
new Greeter().sayHello()
これはうまくいきませんでした:
groovy.lang.MissingPropertyException: No such property: greeting for class: groovy.lang.MetaClassImpl
少し試した後、self への参照をメソッドに渡すとうまくいくことがわかりました。だから、基本的に私が思いついたのはこれでした:
class Greeter {
def sayHello(self) {
assert this == self
// assert this.metaClass == self.metaClass
self.metaClass.greeting = { System.out.println "Hello!" }
greeting()
}
}
def greeter = new Greeter()
greeter.sayHello(greeter)
最も奇妙なことは、assert this == self
実際に合格することです。つまり、それらは同じインスタンスです...そうですか?デフォルトtoString
もこれを確認しているようです。
一方、assert this.metaClass == self.metaClass
失敗します:
assert this.metaClass == self.metaClass
| | | |
| | | org.codehaus.groovy.runtime.HandleMetaClass@50c69133[groovy.lang.MetaClassImpl@50c69133[class Greeter]]
| | Greeter@1c66d4b3
| false
groovy.lang.MetaClassImpl@50c69133[class Greeter]
self.metaClass が HandleMetaClass にラップされているのに、this.metaClass がラップされていないのはなぜですか? また、self への参照を渡さずに最初の例を機能させるにはどうすればよいでしょうか?