I would like help understanding how Groovy manages scope and variables when passed between functions. Say I declare def foo in my main method and pass it as an argument to a private void method, changeStuff. Then I can make changes like follows:
public static void main(args) {
def foo = [:];
changeStuff(foo);
println(foo);
}
private static void changeStuff(foo) {
foo.bar = "new stuff";
}
The result printed is [bar:new stuff] But I have a hard time manipulating foo in other ways. See these next two examples:
public static void main(args) {
def foo = [:];
changeStuff(foo);
println(foo);
}
private static void changeStuff(foo) {
def newStuff = [:]
newStuff.extra = "extra stuff";
foo = newStuff;
}
prints: [:]
public static void main(args) {
def foo = "before";
changeStuff(foo);
println(foo);
}
private static void changeStuff(foo) {
foo = "after";
}
prints before
I know there is some concept here that I am not fully understanding, maybe related to def? Any summary or direction on where I can learn more about this is appreciated.
My experience in groovy is very limited, so I might be off a bit.
In the first case you mention, you are passing
fooby reference tochangeStuff, and inside the method, you directly modify the map, so changes are visible from yourmainmethod.In the second case, the parameter
fooinside yourchangeStuffmethod is being assigned to another map. However, the variablefooinside yourmainmethod still points to the first map you have created, thus the empty map when you print it.The third case is the same as the second case. Plus, you have to be aware that
Stringobjects in Java (and probably in Groovy too) are immutable. So when “modifying” aString, what you are really doing is creating a new instance each time.