Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy scope - how to access script variable in a method

Tags:

scope

groovy

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 MissingPropertyExceptions 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:

  1. Why can't I access a variable annotated with @Field inside method()?
  2. How can I refer to a script variable inside method()?
like image 228
amarillion Avatar asked Mar 25 '13 15:03

amarillion


People also ask

How do you call a variable in Groovy?

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.

How do you set a global variable in Groovy?

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. }

What do you call a variable that can be accessed from all scopes?

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.

Which scope variables are declared and accessed anywhere in script?

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.


1 Answers

When you have methods or statements outside of a class declaration in a groovy script, an implicit class is created. To answer your questions:

  1. 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.

  2. 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(); 
like image 117
ataylor Avatar answered Sep 22 '22 05:09

ataylor