[ 
https://issues.apache.org/jira/browse/GROOVY-7399?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14509948#comment-14509948
 ] 

Geoffrey Miller edited comment on GROOVY-7399 at 4/23/15 10:21 PM:
-------------------------------------------------------------------

I've been away from Java for more than a few years, but let me see if I can 
tackle this.

First off, I wouldn't expect the assert to pass. Here's why.

Let's take a look at the last two lines of your code.

Bar b = new Bar()
assert b.hiFoo() == b.f.whoAmI()

At this point, b.hiFoo() should return "It's Bar" because in your Bar class, 
you defined whoAmI() to return this value. Thus, that's what gets assigned to 
the whoAmI() in your FooTrait, that is, f.with the Bar definition of whoAmI() 
as found in the Bar class. 

On the other hand, b.f.whoAmI() bypasses the Bar class, so to speak. Thus, the 
definition of whoAmI() that returns "It's Foo" sticks. 

I don't think this is necessarily a bug, unless of course it conflicts with how 
we want traits to work when conflicting definitions pop up. To me, it makes 
sense to be able to bypass the Bar class' definition of whoAmI() to access how 
it's defined in the trait, FooTrait. So, to answer the question posed by your 
code...

trait FooTrait {
    Foo f = new Foo()
    def hiFoo() {
        f.with {
            whoAmI() // it's Foo or Bar?!
        }
    }
}

...whoAmI() is "It's Bar" when accessed as a trait of the class Bar and "It's 
Foo" when accessed as a definition within the Foo class. Does that make sense?

Also, how do you do formatting in the comments like the OP?


was (Author: geoffreyonwheels):
I've been away from Java for more than a few years, but let me see if I can 
tackle this.

First off, I wouldn't expect the assert to pass. Here's why.

Let's take a look at the last two lines of your code.

Bar b = new Bar()
assert b.hiFoo() == b.f.whoAmI()

At this point, b.hiFoo() should return "It's Bar" because in your Bar class, 
you defined whoAmI() to return this value. Thus, that's what gets assigned to 
the whoAmI() in your FooTrait. 

On the other hand, b.f.whoAmI() bypasses the Bar class, so to speak. Thus, the 
definition of whoAmI() that returns "It's Foo" sticks. 

I don't think this is necessarily a bug, unless of course it conflicts with how 
we want traits to work when conflicting definitions pop up. To me, it makes 
sense to be able to bypass the Bar class' definition of whoAmI() to access how 
it's defined in the trait, FooTrait. So, to answer the question posed by your 
code...

trait FooTrait {
    Foo f = new Foo()
    def hiFoo() {
        f.with {
            whoAmI() // it's Foo or Bar?!
        }
    }
}

...whoAmI() is "It's Bar" when accessed as a trait of the class Bar and "It's 
Foo" when accessed as a definition within the Foo class. Does that make sense?

Also, how do you do formatting in the comments like the OP?

> Method "with()" fails to call on the object reference in Trait
> --------------------------------------------------------------
>
>                 Key: GROOVY-7399
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7399
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>            Reporter: Terry Wong
>
> {code}
> class Bar implements FooTrait {
>     def whoAmI() { "It's Bar" }
> }
> class Foo {
>     def whoAmI() { "It's Foo" }
> }
> trait FooTrait {
>     Foo f = new Foo()
>     def hiFoo() {
>         f.with {
>             whoAmI() // it's Foo or Bar?!
>         }
>     }
> }
> Bar b = new Bar()
> assert b.hiFoo() == b.f.whoAmI()
> {code}
> I would expect the {{assert}} on last line will pass, but it failed with
> {noformat}
> Assertion failed: 
> assert b.hiFoo() == b.f.whoAmI()
>        | |       |  | | |
>        | It's Bar|  | | It's Foo
>        |         |  | Foo@72967906
>        |         |  Bar@5b8dfcc1
>        |         false
>        Bar@5b8dfcc1
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to