In groovy 1.8.6, I was trying to do something like this:
class Greeter {
def sayHello() {
this.metaClass.greeting = { System.out.println "Hello!" }
greeting()
}
}
new Greeter().sayHello()
This didn't work:
groovy.lang.MissingPropertyException: No such property: greeting for class: groovy.lang.MetaClassImpl
After a bit of trying, I found that passing a reference to self to the method did work. So, basically what I came up with was this:
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)
The strangest thing is that the assert this == self
actually passes, which means they are the same instance... right? The default toString
also seems to confirm this.
On the other hand, the assert this.metaClass == self.metaClass
fails:
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]
Why is self.metaClass wrapped in a HandleMetaClass, while this.metaClass isn't? Also, how can the first example be made to work without passing in a reference to self?