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:
@Field
inside method()
? method()
?Variables in Groovy can be defined in two ways − using the native syntax for the data type or the next is by using the def keyword. For variable definitions it is mandatory to either provide a type name explicitly or to use "def" in replacement. This is required by the Groovy parser.
import groovy. transform. Field var1 = 'var1' @Field String var2 = 'var2' def var3 = 'var3' void printVars() { println var1 println var2 println var3 // This won't work, because not in script scope. }
Output: 5 10. In the program, the variable “global” is declared at the top of the program outside all of the functions so it is a global variable and can be accessed or updated from anywhere in the program.
Global variable The global variables are the variables that are declared outside the function. These variables can be accessed anywhere in the program. To access the global variable within a function, use the GLOBAL keyword before the variable.
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With