I was trying to debug some code that uses mixins and I was able to reduce my problem down to this example. I have a parent class that receives methods via a mixin and a child class that inherits from the parent. If I try to replace a method on an instance of the child class it works UNLESS the method that I'm replacing was called on an instance of the parent class before it is replaced. If it has been called then I can't replace it
So this code:
class M {
protected foo() { println 'foo' }
}
@Mixin(M) class A {
def bar() { foo() }
}
class B extends A {}
def b = new B()
def a = new A()
a.bar() //<-- comment out this line and see the difference
b.metaClass.foo = {println 'winning'}
b.bar()
Will yield:
foo
foo
But if you comment out line 13 (the one with the comment that says to comment it out) you'll get:
winning
Why does this happen? I expect there is some way this makes sense within the context of Groovy's metaclass model, but I don't get it.
This is Groovy 1.8.6