aetheria aetheria - 1 month ago 5
Groovy Question

Variable visibility in a Groovy Script

I have created a

temp.groovy
script:

def loggedMessages = [];

def log(message) {
loggedMessages << message;
}

log "Blah"

print loggedMessages.join('\n')


When I run it I get an exception relating to the log method:

groovy.lang.MissingPropertyException: No such property: loggedMessages


Why can't the log method see the loggedMessages variable? I obviously have a fundamental misunderstanding of what's going on. I've tried to read the docs but I can't seem to find the relevant section.

Answer

From the comments, as an answer:

The Script class documentation states (in the last section 3.4 Variables) that:

if the variable is declared as in the first example [with a type definition], it is a local variable. It will be declared in the run method that the compiler will generate and will not be visible outside of the script main body. In particular, such a variable will not be visible in other methods of the script

And further: if the variable is undeclared, it goes into the script binding. The binding is visible from the methods [...]

Therefore removing the def from loggedMessages fixes the error:

loggedMessages = [];

def log(message) {
    loggedMessages << message;
}

log "Blah"

print loggedMessages.join('\n')

(Alternatively it can be annotated using @groovy.transform.Field as @aetheria pointed out in the comments)