The closure you have defined does not store anything in binding
object - it simply returns String passed as str
variable, repeated 4 times.
This binding
object stores all variables that were defined without specifying their types or using def
keyword. It is done via Groovy metaprogramming feature (getProperty
and setProperty
methods to be more specific). So when you define a variable s
like:
def clsr = {
s = str*4
return s
}
then this closure will create a binding with key s
and value evaluated from expression str * 4
. This binding object is nothing else than a map that is accessed via getProperty
and setProperty
method. So when Groovy executes s = str * 4
it calls setProperty('s', str * 4)
because variable/property s
is not defined. If we make a slightly simple change like:
def clsr = {
def s = str*4 // or String s = str * 4
return s
}
then binding s
won't be created, because setProperty
method does not get executed.
Another comment to your example. If you want to see anything in binding object, you need to call returned closure. In example you have shown above the closure gets returned, but it never gets called. If you do:
def c = fourtify("aa")
c.call()
println("binding variables: ${c.getBinding().getVariables()}")
then your closure gets called and binding object will contain bindings (if any set). Now, if you modify your example to something like this:
def fourtify(String str) {
def clsr = {
def n = 4 // it does not get stored as binding
s = str * n
return s
}
return clsr
}
def c = fourtify("aa")
c.call()
println("binding variables: ${c.getBinding().getVariables()}")
you will see following output in return:
binding variables: [args:[], s:aaaaaaaa]
Hope it helps.