I came across something with Groovy shutting down and delegates whom I am not sure is an official part of the language or possibly even a mistake.
Basically, I define a closure, which I read as a string from an external source, and one of the variables in the class that defines the closure must be modified by the closure. I wrote a simple example showing what I found works and what doesn't work.
If you look at the test code below, you will see a class that defines a variable
animal = "cat"
and two closures, defined on the go from the lines that try to change the animal variable.
It works>
String code = "{ -> delegate.animal = 'bear'; return name + 'xx' ; }"
But it is not
String code = "{ -> animal = 'bear'; return name + 'xx' ; }"
It looks like I need to explicitly assign the variable to-be-modified using "delegate". for this to work. (I think I can also define a setter in the enclosing class to close to cause a change in value.)
So ... I found out how to make this work, but I would be interested if someone could point me to some Groovy doc that explains the rules behind it.
In particular .... why a simple appointment
animal = 'bear'
affects the original variable? Are there shadow copies here or something else?
import org.junit.Test /* * Author: cbedford * Date: 8/30/12 * Time: 1:16 PM */ class GroovyTest { String animal = "cat" String name = "fred" @Test public void testDelegateWithModificationOfDelegateVariable() { String code = "{ -> delegate.animal = 'bear'; return name + 'xx' ; }" def shell = new GroovyShell() def closure = shell.evaluate(code) closure.delegate = this def result = closure() println "result is $result" println "animal is $animal" assert animal == 'bear' assert result == 'fredxx' } // This test will FAIL. @Test public void testDelegateWithFailedModificationOfDelegateVariable() { String code = "{ -> animal = 'bear'; return name + 'xx' ; }" def shell = new GroovyShell() def closure = shell.evaluate(code) closure.delegate = this def result = closure() println "result is $result" println "animal is $animal" assert animal == 'bear' assert result == 'fredxx' } }
scope closures groovy
Chris bedford
source share