I have a Groovy trait which needs to provide a config Closure as an argument to a library method call (it's HttpBuilder but it shouldn't matter).
For reproducing the issue, I created the following simple example:
trait T {
def doIt() {
return {
n = 1
}
}
}
class Delegate {
int n
}
class Tish implements T {
def go() {
def closure = doIt()
def d = new Delegate()
closure.delegate = d
closure()
assert d.n == 1
}
}
new Tish().go()
This is expected to run without errors because when the closure returned by the doIt()
method in the T
trait is run, its delegate is set to something that can set the n
variable to 1....
However, this does not work and I get this error:
groovy.lang.MissingPropertyException: No such property: n for class: Tish
If I make T
a class and let Tish
extend it instead, then it works!
I tried changing the Closure's delegate strategy but that did not help.
Is this a Groovy bug or is there a way to work around this issue?
Alright, I found a workaround... Still, would be interesting to know if this is a bug, and if it is, when it will get fixed by the Groovy team!
UPDATE: this is a bug and hopefully will be fixed in a Groovy release in the near future!
All calls made within the config Closure can get the actual Delegate object by calling the getDelegate()
method, then setting all properties directly on it, like this:
return {
def d = getDelegate()
d.n = 1
}
Not ideal, but got me unstuck, hope it helps others...
EDIT: As pointed about by @bdkosher in the comments, another solution is to use setter syntax in the closure:
return {
setN 1
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With