On 14.10.20 13:45, Anton Shepelev wrote:
[...]
    String test

defienes a string property `test' or a string variable
`test', depending on context.

the context here is that of a method, so it is a local variable

I was now stuck and resorted
to an internet search, which brought up the following page

    Groovy Variable Scope:
    https://www.baeldung.com/groovy/variable-scope

where I read:

    Scopes in Groovy follow, above all, the rule that all
    variables are created public by default. This means that,
    unless specified, we'll be able to access any variable we
    created from any other scope in the code.

Why, then, is `test' inaccessible from the function in my
script?

because the method you defined is not nested in another method, instead
it exists parallel to the other method that represents your script body,
and they do not share local variables. Frankly... for years we have been
defending this position, but now, with so much distance I actually
really wonder why we keep this. It comes up as a problem on a regular
base, but wouldn't be so hard to "fix" really. I mean it is not broken,
it works as designed, just not very intuitive.

 And below:

    The easiest way to create a global variable in a Groovy
    script is to assign it anywhere in the script without any
    special keywords. We don't even need to define the type:

       x = 200

After I removed the "String test" line from my script it
started to work, but why?

without the declaration you are writing to a outer scope variable, which
in case of a script usually ends up in the binding. A variable in the
binding of a script is defined by writing it. Reading a non-existent
variable would cause an error.

I returned to the "Semantics"
document and read section 1.2. (Variable assignment) to see
whether the assignment operator may have the side effect of
defining a missing variable, but there is no indication that
it has.

it is actually less the assignment operator itself, it is the effect of
scopes of dynamic variables. To compare.. in Java you have a static
scope for a variable. The compiler knows at any time where a variable is
declared, and where to write it to (local variable or class). In Groovy
we also have the static variable scopes, but they are "extended" in
dynamic Groovy with dynamic variables. This means the (meta) class is
"asked" for the value and existence of a variable at runtime as soon as
we leave the static scope. In Java leaving the static scope would mean
an compilation error. But in Groovy we are then using the MOP to find
meaning in what is requested. In case of a Closure this results in
checking the enclosed scope for the value of a variable. In case of a
class this results in set/getProperty and similar methods being called
as part of the MOP. A Groovy script is a class too, only that its
getProperty method checks the binding for the value and setProperty
writes it. There is no formal way to declare a variable in a binding, it
is solely defined by the program writing it. As such it has no static
type (as all dynamic variables).

I would have loved to point to our documentation for this, but I
actually am unable to find this there. I actually thought I have written
something years ago (back when it was still codehaus), but I cannot find
any trace of that either.... I guess I should really get used to write
everything I write for a project also on my blog, so that I can have at
least one original reference. So no references I am aware of, sorry

bye Jochen


Reply via email to