groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jochen Theodorou <>
Subject Re: Closure does not see field when setting value
Date Thu, 10 Nov 2016 10:14:29 GMT

On 10.11.2016 10:36, Krzysztof Kowalczyk wrote:
>> so how do you define a variable and use that variable in a method in a
> script?
> A variable that is accessible to a method sound a lot like a field to
> me. Thus my usage of @Field.

Now imagine scripts in Groovy being much older than @Field. So how do 
you do it if @Field cannot be used?

> It would be nice if it would be imported in
> all scripts by default. If not for the binding it would also act exactly
> the same with or without compile static, which is another plus side. Of
> course I would still want to be able to set binding for script context
> in general and be able to read them. That said, if I want to export a
> binding to external world I would prefer some special way of doing that.

in short you would need to completely redefine the interaction with 
Binding. I am not saying that today's way is the right one, just saying 
that this is the way that made most sense at the time. Variable scoping 
looked quite different than today back then in 2005. It might be that a 
different script logic should be chosen, but that is why script base 
class exists.

> In Gradle to create a "global" variable one use ext.x = 1
> In Beaker notebook to create a variable that is shared across sections
> one do beaker.x = 1

not sure gradle is a good example. "ext.x = 1" sets the variable x with 
value 1 for the external context, but in terms of a global variable 
residing in the binding you would just do "x=1". But "x=1" is not just 
"x=1", the semantics depends on what x is. If x is no local variable, 
then it means something like "iThis.x=1", where iThis is the implicit 
this. And the meaning of the implicit this can be changed in for example 
an open block. So If I do

task myTask(dependsOn:anotherTask) {
   x = 1

I actually have

task(myTask(dependsOn:anotherTask, {
   x =  1

and if I here set the delegate (thus change the meaning of the implicit 
this) to capture the x=1 call and set it to make it part of the object 
that represents the task myTask, then I can later do println myTask.x 
and get the value 1.

So we can't you just do x=1 in a gradle script? because the delegate 
used for the tasks will not relay calls to the binding. There are a 
"capture all" type. Thus if you need to access something outside of the 
context of the task you have to use the bridges defined for the task. 
And ext is one such bridge. Which means you have to do ext.x = 1 if you 
do not want to set the task property x. Or you do "this.x = 1", which 
would end up in the binding. But since I never tried the last one I 
cannot tell if that would work, since Gradle may have set a Binding that 
just rejects everything.

bye Jochen

View raw message