Groovy scope - how to access script variable in a method
groovy, scope
Solution
When you have methods or statements outside of a `class` declaration in a groovy script, an implicit class is created. To answer your questions:
In your example, `func()` can access the field `c` because they are both members of the implicit class. The `Main` class is not, so it can't.
You need to pass a reference to the script variable to `method()`. One way is to pass the implicitly defined `binding` object, through which you can access all the script scope variables.
Example:
#!/usr/bin/groovy
import groovy.transform.Field;
//println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
def a = 42;
b = "Tea"
@Field def c = "Cheese"
void func()
{
// println a // MissingPropertyException
println b // prints "Tea"
println c // prints "Cheese" with groovy 2.1.2, MissingPropertyException with groovy 1.8.6
}
class Main
{
def scriptObject
def binding
def method()
{
// println a // MissingPropertyException
println binding.b
println scriptObject.c
}
}
func();
new Main(scriptObject: this, binding: binding).method();
Problem
I have a question about scoping rules in Groovy. In the following snippet, I have three variables, `a` has local scope, `b` has script scope, and `c` should get script scope as well using the `@Field` annotation. ``` #!/usr/bin/groovy import groovy.transform.Field; //println org.codehaus.groovy.runtime.InvokerHelper.getVersion() def a = 42; b = "Tea" @Field def c = "Cheese" void func() { // println a // MissingPropertyException println b // prints "Tea" println c // prints "Cheese" with groovy 2.1.2, MissingPropertyException with groovy 1.8.6 } class Main { def method() { // println a // MissingPropertyException // println b // MissingPropertyException // println c // MissingPropertyException with both 1.8.6. and 2.1.2 } } func(); new Main().method(); ``` I get `MissingPropertyException`s on the lines indicated with comments. The exceptions on `a` are expected, as that variable has local scope. But I would expect `b` to be accessible inside `method()` - it isn't. `@Field` doesn't do anything in groovy 1.8.6, although after upgrading it works, so I guess that is an old bug. Nevertheless, `c` is inaccessible inside `method()` with either version. So my questions are: - Why can't I access a variable annotated with `@Field` inside `method()`? - How can I refer to a script variable inside `method()`?