groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Krzysztof Kowalczyk <kowalczyk.krzysz...@gmail.com>
Subject Re: Closure does not see field when setting value
Date Thu, 10 Nov 2016 11:19:50 GMT
> this is the way that made most sense at the time

I agree and understand that. I just not sure if it is the right way to go
for future. I expect that mop2 would break some runtime behaviours, so that
might be the one good point in time to reevaluate some past decisions.
Nevertheless, I don't know if this particular behaviour should change at
all as I don't know all use cases people have.

Because Gradle is "not a good example" it actually is one - it show the
same problem. In general in Groovy based tools it is relatively hard to
define variable visible to methods and any change of base script may change
this behaviour and users are not safe to assume it would work the same way
between tools (gradle, job dsl, simple scripts, beaker notebook etc). Maybe
there is a way of solving it which could be reused across tools in "Groovy
3". def x is a safe local variable, it would be nice to have same for
script scope (~field) and maybe even global (across scripts).

So maybe I could have something like that
global: int x = 1
binding: int y = 1 or script: y = 1 or bind: int y = 1

where first would be put in well known static map and another in bindings
or some local map. That should be easy to do with global ast
transformation. I would prefer to have something like that as standard which
could be reused across tools instead of introducing my own concepts.

It still leave us with the problem of delegate first that's why I was
thinking of some sort of strategy that would invoke "existing" properties
(those that we can check if they exist) and methods before using get,
getProperty, methodMissing etc.

Regards,
Krzysztof

On 10 November 2016 at 10:14, Jochen Theodorou <blackdrag@gmx.org> wrote:

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

Mime
View raw message