Reputation: 431
I am new to Groovy and confusing about the variable scope in closure.
For example, the code below works fine. It prints two 5.
def x = 10
def y = 25
def myfunc(x) {
return {
println(x)
insideFunc(x)
}
}
def insideFunc(x) {
println(x)
}
closureFunc = myfunc(5)
closureFunc.call()
But the code below would show error: groovy.lang.MissingPropertyException: No such property: x for class. Why? I thought the insideFunc can access the global variable 'x'?
def x = 10
def y = 25
def myfunc(x) {
return {
println(x)
insideFunc()
}
}
def insideFunc() {
println(x)
}
closureFunc = myfunc(5)
closureFunc.call()
Upvotes: 2
Views: 3384
Reputation: 45309
The problem with the second script is due to how the script is executed. x
is local-scoped in the run
method. That should become evident when one looks at what the script turns into when it's executed. From groovyConsole, the following is what "Inspect AST" displays (this is incomplete):
public class script1526974299557 extends groovy.lang.Script {
...
public java.lang.Object run() {
java.lang.Object x = 10
java.lang.Object y = 25
closureFunc = this.myfunc(5)
closureFunc.call()
}
public java.lang.Object myfunc(java.lang.Object x) {
return {
this.println(x)
this.insideFunc()
}
}
public java.lang.Object insideFunc() {
this.println(x)
}
}
Clearly, x
is out of scope for insideFunc()
.
Regarding the first version, however, things look different. As insideFunc()
takes a parameter, it's argument is carried by the closure:
public class script1526974614817 extends groovy.lang.Script {
...
public java.lang.Object myfunc(java.lang.Object x) {
return {
this.println(x)
this.insideFunc(x)
}
}
public java.lang.Object insideFunc(java.lang.Object x) {
this.println(x)
}
}
Upvotes: 2