You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by Gerald Wiltse <je...@gmail.com> on 2016/02/29 03:23:00 UTC

Confirming getProperties() works differently (inside vs outside)

Is there a way for the Chameleon class to ever see that it has a
"lastColor" property?

class Chameleon{
    String color = "green"

    void printAllMyProperties(){
         this.properties.each{println it}
    }

}

trait ColorChanging {
    String lastColor
    def changeColor = {newcolor ->
        lastColor = this.color
        this.color = newcolor
    }
}

def mylizard = new Chameleon().withTraits(ColorChanging)

mylizard.changeColor(blue)

mylizard.printAllMyProperties()
mylizard.properties.each{println it}

The outputs of the two above lines don't match. lastColor isn't available
from inside the class.

This seems like it should be possible, but I tried several things including
the declaredFields property and could not get the desired effect.

In this script, I'm looking for a way for my instance to reference all the
properties it's received from the trait. I guess it's same situation with
inheritance, and properties added by propertymissing.




Gerald R. Wiltse
jerrywiltse@gmail.com

Re: Confirming getProperties() works differently (inside vs outside)

Posted by Dinko Srkoč <di...@gmail.com>.
On 29 February 2016 at 13:48, Gerald Wiltse <je...@gmail.com> wrote:
> This looks like an elegant solution. Are you confirming that there's no way
> for a method inside "class Chameleon" to achieve the goal?   Just by moving
> method out to a trait, it becomes aware of all the inherited and implemented
> props?  Not bad...

I think I'd much rather Cédric or Jochen confirm and explain this. I
don't feel I could give you a fully accurate answer here - sorry.

Cheers,
Dinko

>
> THANKS!  this list has been really awesome for learning.
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
>
>
> On Mon, Feb 29, 2016 at 4:30 AM, Dinko Srkoč <di...@gmail.com> wrote:
>>
>> I know this is not exactly what you asked, but would something like
>> this work for you?
>>
>>     class Chameleon{ String color = "green" }
>>
>>     trait ColorChanging {
>>         String lastColor
>>         def changeColor = {newcolor ->
>>             lastColor = this.color
>>             this.color = newcolor
>>         }
>>     }
>>
>>     trait MyProps {
>>         void printAllMyProperties(){
>>             this.properties.each{println it}
>>         }
>>     }
>>
>>     def mylizard = new Chameleon().withTraits(ColorChanging, MyProps)
>>
>>     mylizard.changeColor('blue')
>>
>>     mylizard.printAllMyProperties()
>>     mylizard.properties.each{println it}
>>
>> Cheers,
>> Dinko
>>
>> On 29 February 2016 at 03:23, Gerald Wiltse <je...@gmail.com> wrote:
>> > Is there a way for the Chameleon class to ever see that it has a
>> > "lastColor"
>> > property?
>> >
>> > class Chameleon{
>> >     String color = "green"
>> >
>> >     void printAllMyProperties(){
>> >          this.properties.each{println it}
>> >     }
>> >
>> > }
>> >
>> > trait ColorChanging {
>> >     String lastColor
>> >     def changeColor = {newcolor ->
>> >         lastColor = this.color
>> >         this.color = newcolor
>> >     }
>> > }
>> >
>> > def mylizard = new Chameleon().withTraits(ColorChanging)
>> >
>> > mylizard.changeColor(blue)
>> >
>> > mylizard.printAllMyProperties()
>> > mylizard.properties.each{println it}
>> >
>> > The outputs of the two above lines don't match. lastColor isn't
>> > available
>> > from inside the class.
>> >
>> > This seems like it should be possible, but I tried several things
>> > including
>> > the declaredFields property and could not get the desired effect.
>> >
>> > In this script, I'm looking for a way for my instance to reference all
>> > the
>> > properties it's received from the trait. I guess it's same situation
>> > with
>> > inheritance, and properties added by propertymissing.
>> >
>> >
>> >
>> >
>> > Gerald R. Wiltse
>> > jerrywiltse@gmail.com
>> >
>
>

Re: Confirming getProperties() works differently (inside vs outside)

Posted by Gerald Wiltse <je...@gmail.com>.
This looks like an elegant solution. Are you confirming that there's no way
for a method inside "class Chameleon" to achieve the goal?   Just by moving
method out to a trait, it becomes aware of all the inherited and
implemented props?  Not bad...

THANKS!  this list has been really awesome for learning.

Gerald R. Wiltse
jerrywiltse@gmail.com


On Mon, Feb 29, 2016 at 4:30 AM, Dinko Srkoč <di...@gmail.com> wrote:

> I know this is not exactly what you asked, but would something like
> this work for you?
>
>     class Chameleon{ String color = "green" }
>
>     trait ColorChanging {
>         String lastColor
>         def changeColor = {newcolor ->
>             lastColor = this.color
>             this.color = newcolor
>         }
>     }
>
>     trait MyProps {
>         void printAllMyProperties(){
>             this.properties.each{println it}
>         }
>     }
>
>     def mylizard = new Chameleon().withTraits(ColorChanging, MyProps)
>
>     mylizard.changeColor('blue')
>
>     mylizard.printAllMyProperties()
>     mylizard.properties.each{println it}
>
> Cheers,
> Dinko
>
> On 29 February 2016 at 03:23, Gerald Wiltse <je...@gmail.com> wrote:
> > Is there a way for the Chameleon class to ever see that it has a
> "lastColor"
> > property?
> >
> > class Chameleon{
> >     String color = "green"
> >
> >     void printAllMyProperties(){
> >          this.properties.each{println it}
> >     }
> >
> > }
> >
> > trait ColorChanging {
> >     String lastColor
> >     def changeColor = {newcolor ->
> >         lastColor = this.color
> >         this.color = newcolor
> >     }
> > }
> >
> > def mylizard = new Chameleon().withTraits(ColorChanging)
> >
> > mylizard.changeColor(blue)
> >
> > mylizard.printAllMyProperties()
> > mylizard.properties.each{println it}
> >
> > The outputs of the two above lines don't match. lastColor isn't available
> > from inside the class.
> >
> > This seems like it should be possible, but I tried several things
> including
> > the declaredFields property and could not get the desired effect.
> >
> > In this script, I'm looking for a way for my instance to reference all
> the
> > properties it's received from the trait. I guess it's same situation with
> > inheritance, and properties added by propertymissing.
> >
> >
> >
> >
> > Gerald R. Wiltse
> > jerrywiltse@gmail.com
> >
>

Re: Confirming getProperties() works differently (inside vs outside)

Posted by Dinko Srkoč <di...@gmail.com>.
I know this is not exactly what you asked, but would something like
this work for you?

    class Chameleon{ String color = "green" }

    trait ColorChanging {
        String lastColor
        def changeColor = {newcolor ->
            lastColor = this.color
            this.color = newcolor
        }
    }

    trait MyProps {
        void printAllMyProperties(){
            this.properties.each{println it}
        }
    }

    def mylizard = new Chameleon().withTraits(ColorChanging, MyProps)

    mylizard.changeColor('blue')

    mylizard.printAllMyProperties()
    mylizard.properties.each{println it}

Cheers,
Dinko

On 29 February 2016 at 03:23, Gerald Wiltse <je...@gmail.com> wrote:
> Is there a way for the Chameleon class to ever see that it has a "lastColor"
> property?
>
> class Chameleon{
>     String color = "green"
>
>     void printAllMyProperties(){
>          this.properties.each{println it}
>     }
>
> }
>
> trait ColorChanging {
>     String lastColor
>     def changeColor = {newcolor ->
>         lastColor = this.color
>         this.color = newcolor
>     }
> }
>
> def mylizard = new Chameleon().withTraits(ColorChanging)
>
> mylizard.changeColor(blue)
>
> mylizard.printAllMyProperties()
> mylizard.properties.each{println it}
>
> The outputs of the two above lines don't match. lastColor isn't available
> from inside the class.
>
> This seems like it should be possible, but I tried several things including
> the declaredFields property and could not get the desired effect.
>
> In this script, I'm looking for a way for my instance to reference all the
> properties it's received from the trait. I guess it's same situation with
> inheritance, and properties added by propertymissing.
>
>
>
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
>

Re: Confirming getProperties() works differently (inside vs outside)

Posted by Gerald Wiltse <je...@gmail.com>.
Ok, so it's a symptom of calling withTraits dynamically, now it makes
sense. That's much less common of a use case than standard trait
implementation.

While I would think a "groovy reflection" feature to capture these types of
properties would make a lot of sense, I can see this being very difficult
if not impossible, since it would require someone to override "this"
keyword, and replace it with new reflection logic.  I guess if someone
decided to try to such a feature, it would be better to use a different
keyword like thisMeta or something. The workaround from dinko is extremely
easy considering the problem. Thanks both of you.

Gerald R. Wiltse
jerrywiltse@gmail.com


On Mon, Feb 29, 2016 at 8:17 AM, Jochen Theodorou <bl...@gmx.org> wrote:

>
>
> On 29.02.2016 03:23, Gerald Wiltse wrote:
>
>> Is there a way for the Chameleon class to ever see that it has a
>> "lastColor" property?
>>
>> class Chameleon{
>>      String color = "green"
>>
>>      void printAllMyProperties(){
>>           this.properties.each{println it}
>>      }
>>
>> }
>>
>> trait ColorChanging {
>>      String lastColor
>>      def changeColor = {newcolor ->
>>          lastColor = this.color
>>          this.color = newcolor
>>      }
>> }
>>
>
> in case of Chameleon implements ColorChanging the answer is yes. In case of
>
> def mylizard = new Chameleon().withTraits(ColorChanging)
>>
>> mylizard.changeColor(blue)
>>
>> mylizard.printAllMyProperties()
>> mylizard.properties.each{println it}
>>
>
> ... no. Here Chameleon does not know anything about the trait and the
> trait isused like a facade around the object. For the same reason mylizard
> is an instance of ColorChanging, but not of Chameleon anymore
>
> It could probably made possible, if you change the meta class used for the
> Chameleon object you proxy with the trait. But there is no such
> implementation right now
>
> bye Jochen
>

Re: Confirming getProperties() works differently (inside vs outside)

Posted by Jochen Theodorou <bl...@gmx.org>.

On 29.02.2016 03:23, Gerald Wiltse wrote:
> Is there a way for the Chameleon class to ever see that it has a
> "lastColor" property?
>
> class Chameleon{
>      String color = "green"
>
>      void printAllMyProperties(){
>           this.properties.each{println it}
>      }
>
> }
>
> trait ColorChanging {
>      String lastColor
>      def changeColor = {newcolor ->
>          lastColor = this.color
>          this.color = newcolor
>      }
> }

in case of Chameleon implements ColorChanging the answer is yes. In case of

> def mylizard = new Chameleon().withTraits(ColorChanging)
>
> mylizard.changeColor(blue)
>
> mylizard.printAllMyProperties()
> mylizard.properties.each{println it}

... no. Here Chameleon does not know anything about the trait and the 
trait isused like a facade around the object. For the same reason 
mylizard is an instance of ColorChanging, but not of Chameleon anymore

It could probably made possible, if you change the meta class used for 
the Chameleon object you proxy with the trait. But there is no such 
implementation right now

bye Jochen