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