Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

access global variable in static scope

Tags:

groovy

Is there a way to access global variable, declared in the script, from the static method of the class, declared in the same script?

For example

def s = "12345"

class MyClass {
    static def method() {
        println s
    }
}

Because that way it fails with the error

You attempted to reference a variable in the binding or an instance variable from a static context

which is expected though.

like image 612
lapots Avatar asked Feb 15 '16 19:02

lapots


People also ask

Can we use global variable inside static method?

Static variables can be declared both inside and outside the main function, while global variables are always declared outside the main function.

How do you access global variable in local scope?

It is the variable that is visible from all other scopes. We can access global variable if there is a local variable with same name in C and C++ through Extern and Scope resolution operator respectively.

What is the scope of a static global variable?

A global static variable is one that can only be accessed in the file where it is created. This variable is said to have file scope. In C, the preprocessor directive #define was used to create a variable with a constant value.

Can we access static global variable in another file?

Static variables in C have the following two properties: They cannot be accessed from any other file. Thus, prefixes “ extern ” and “ static ” cannot be used in the same declaration. They maintain their value throughout the execution of the program independently of the scope in which they are defined.


2 Answers

There is a related discussion at this question:

Groovy scope - how to access script variable in a method

Related in that both questions refer to using a global variable within a class, but this question differs somewhat in that you are seeking to use a static method which alters how you pass the script instance or binding (2 choices).

Passing the Script's Instance

import groovy.transform.Field

@Field def s = "12345"

class MyClass {
    static def method(si) {      
      return si.s
    }
}

assert MyClass.method(this) == "12345"

Passing the Script's binding

s = "12345" // NOTE: no 'def'

class MyClass {
    static def method(b) {      
      return b.s
    }
}

assert MyClass.method(binding) == "12345"
like image 182
tylerwal Avatar answered Sep 28 '22 04:09

tylerwal


Well, the problem is that in Groovy there is no such thing as a global variable. What is loosely considered a global variable is actually a static property within some class.

For example, if you remove the println line so that the code compiles, you get something like this out of the compiler:

public class script1455567284805 extends groovy.lang.Script { 

    ...

    public java.lang.Object run() {
        return java.lang.Object s = '12345'
    }

    ...

}

public class MyClass implements groovy.lang.GroovyObject extends java.lang.Object { 

    ...

    public static java.lang.Object method() {
        // This is where the println would have been.
        return null
    }

    ...
}

As you can see, an additional class is created and the the s variable is declared within the method run() of that class. This makes the variable inaccessible to your other class.

Note: Removing the def will not address this issue.

Solution

Your best bet is to place your "global variables" into a class, possibly as static properties, like this:

class Global {
    static Object S = "12345"
}

class MyClass {
    static def method() {
        println Global.S
    }
}
like image 35
Emmanuel Rosa Avatar answered Sep 28 '22 05:09

Emmanuel Rosa