I'm trying to change the behaviour of the constructor of a groovy class by replacing a method in that class which is used to set a property but the properties are not getting set with the expected values.
class TestClass {
def noParam
def withParam
TestClass() {
noParam = noParam()
withParam = withParam('second test')
}
def noParam() {
return 'first test'
}
def withParam(param) {
return param
}
}
TestClass.metaClass.withParam = { param -> 'pass' }
TestClass.metaClass.noParam = {-> 'pass' }
def test = new TestClass()
assert test.withParam('dummy') == 'pass' //passes
assert test.withParam == 'pass' // fails
assert test.noParam() == 'pass' // passes
assert test.noParam == 'pass' // fails
Groovy is not using your metaclass overrides in the TestClass constructor when it executes the noParam
and withParam
methods. In fact, if you type the parameter in your withParam
method, the 2nd assert will also fail.
class TestClass {
def noParam
def withParam
TestClass() {
noParam = noParam()
withParam = withParam('second test')
println "in the constructor: noParam = $noParam, withParam = $withParam"
}
def noParam() {
return 'first test'
}
def withParam(String param) {
return param
}
}
TestClass.metaClass.withParam = { String param -> 'pass' }
TestClass.metaClass.noParam = {-> 'pass' }
def test = new TestClass()
assert test.withParam('dummy') == 'pass'
assert test.withParam == 'pass' // this fails now too!
assert test.noParam() == 'pass'
assert test.noParam == 'pass' // this fails
Here's the output: in the constructor: noParam = first test, withParam = second test
test.withParam
and test.noParam
are actually calling test.getWithParam()
and test.getNoParam()
- they are returning the property values set in the constructor.
test.withParam('dummy')
and test.noParam()
are calling your metaclass method and returning "pass".
As far as why groovy does not use the metaclass method in your constructor, I'm not sure... I couldn't find anything in the metaclass documentation...
Maybe you could use static methods instead?
class TestClass {
def noParam
def withParam
TestClass() {
noParam = TestClass.noParam()
withParam = TestClass.withParam('second test')
println "in the constructor: noParam = $noParam, withParam = $withParam"
}
static def noParam() {
return 'first test'
}
static def withParam(String param) {
return param
}
}
TestClass.metaClass.'static'.withParam = { String param -> 'pass' }
TestClass.metaClass.'static'.noParam = {-> 'pass' }
def test = new TestClass()
assert test.withParam('dummy') == 'pass'
assert test.withParam == 'pass' // passes!
assert test.noParam() == 'pass'
assert test.noParam == 'pass' // passes!
Here's the output: in the constructor: noParam = pass, withParam = pass