You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@groovy.apache.org by Paolo Di Tommaso <pa...@gmail.com> on 2017/06/25 18:35:29 UTC

Re: Add a marker interface to bypass Collections and Maps formatting

Dear all,

Groovy still does not provide a mechanism to override the `toString` and
`equals` methods for custom Collection and Map objects. This is a serious
limitation in some use cases.

I'm proposing with the following pull request to introduce a marker
annotation that allows a custom object to use the `toString` and `equals`
as expected.

https://github.com/apache/groovy/pull/566


Any comment or improvement is welcome.


Cheers,
Paolo


On Thu, Jun 2, 2016 at 1:38 AM, Paul King <pa...@asert.com.au> wrote:

> I am +1 on improving how we handle formatting for lists and maps. My
> default position would be -1 on an implementation that smells like it
> might be "yet another hack" that we have to maintain long term. The
> main reason being that we are trying to streamline method selection
> for our revised MOP (I know not much is happening in that space right
> now) and it would be nicer if once that is done, the "inconsistent"
> results you mention could be handled in an easy to understand way.
> Having said that, if I get time to look into it further and can't
> think of a better way to approach it long term, then I could easily be
> moved to at least a -0.
>
> Cheers, Paul.
>
> On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
> <pa...@gmail.com> wrote:
> > Hello guys,
> >
> > No feedback on this? Would you take in consideration a PR for this
> proposal?
> >
> >
> > Thanks,
> > Paolo
> >
> >
> > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
> > <pa...@gmail.com> wrote:
> >>
> >> Hi all,
> >>
> >> Groovy implements a built-in formatting strategy for collection and map
> >> objects that is surely nicer and more useful than the one provided by
> the
> >> default Java implementation for these classes.
> >>
> >> However there are use cases in which custom collection or map classes
> need
> >> to implement their own formatting rule.
> >>
> >> Currently in Groovy this is quite painful and may lead to inconsistent
> >> results. Take in consideration the following example:
> >>
> >> class MyList extends ArrayList {
> >>  String toString() {
> >>     this.join('-')
> >>   }
> >> }
> >>
> >> def x = new MyList()
> >> x << 1 << 2 << 3
> >>
> >> println x.toString()
> >> println x
> >> println "$x"
> >>
> >> Which prints:
> >>
> >> 1-2-3
> >> [1, 2, 3]
> >> [1, 2, 3]
> >>
> >> Both the second and third `println` use the Groovy built-in formatting
> >> method and there's no easy way to override this behaviour. Also there's
> not
> >> a clear reason why the first and the second print return a different
> output.
> >>
> >> The only options I've found is to define `MyList` with a @Delegate
> without
> >> implementing the `List` interface. But this leads to other weird side
> >> effects. The remaining possibility is to use some bytecode manipulation
> to
> >> bypass the default Groovy formatting, but it looks to me a really
> >> overkilling solution for such problem.
> >>
> >> For this reason a would like to propose to introduce a mechanism that
> >> would allow custom collection and map classes to bypass the default
> >> formatting method. This should not be too difficult. The current Groovy
> >> built-in formatting is implemented by formatList and formatMap methods.
> >>
> >> It would be enough to add a marker interface (or an annotation) that
> when
> >> applied to a class it would be used to by-pass the logic in the
> formatList
> >> and formatMap methods and simply return the string provided by the
> object
> >> `toString` method.
> >>
> >>
> >> I could easily contribute this patch however I would know the opinion of
> >> the Groovy core committers. In particular:
> >>
> >> 1) What name should have this marker interface? groovy.lagn.Something?
> >> 2) Are formatList and formatMap methods the right place to add this
> logic?
> >> 3) A similar problem exists also when using the `equals` (and hashCode?)
> >> method for collections and maps. Should this mechanism be extended also
> to
> >> this case?
> >>
> >>
> >>
> >> Best,
> >> Paolo
> >>
> >>
> >
>

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paolo Di Tommaso <pa...@gmail.com>.
I want to report an update on the status of this issue. In the conversation
in the GitHub pull request <https://github.com/apache/groovy/pull/566> I
was requested to perform a benchmark to evaluate  the impact of this
change.

The results are showed below:

Benchmark                        (size)   Mode  Cnt        Score
Error   Units
ListBench.equalsDefaultGroovy         1  thrpt   15  2320508.042 ±
84277.415  ops/ms
ListBench.equalsDefaultGroovy        10  thrpt   15  2329172.399 ±
69070.211  ops/ms
ListBench.equalsDefaultGroovy       100  thrpt   15  2354738.681 ±
64525.890  ops/ms
ListBench.equalsDefaultGroovy      1000  thrpt   15  2358917.549 ±
46171.873  ops/ms
ListBench.equalsDefaultGroovy   1000000  thrpt   15  2377102.274 ±
48227.814  ops/ms
ListBench.equalsWithAnnotation        1  thrpt   15  2213530.048 ±
93671.364  ops/ms
ListBench.equalsWithAnnotation       10  thrpt   15  2277729.772 ±
89214.824  ops/ms
ListBench.equalsWithAnnotation      100  thrpt   15  2256582.572 ±
85712.999  ops/ms
ListBench.equalsWithAnnotation     1000  thrpt   15  2266409.619 ±
45408.683  ops/ms
ListBench.equalsWithAnnotation  1000000  thrpt   15  2197481.973 ±
127202.807  ops/ms
ListBench.equalsWithInterface         1  thrpt   15  2155416.804 ±
80496.840  ops/ms
ListBench.equalsWithInterface        10  thrpt   15  2061873.464 ±
211658.982  ops/ms
ListBench.equalsWithInterface       100  thrpt   15  2106467.218 ±
89659.046  ops/ms
ListBench.equalsWithInterface      1000  thrpt   15  2219947.677 ±
87623.149  ops/ms
ListBench.equalsWithInterface   1000000  thrpt   15  2092834.055 ±
165819.668  ops/ms
ListBench.equalsDefaultGroovy         1   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsDefaultGroovy        10   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsDefaultGroovy       100   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsDefaultGroovy      1000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsDefaultGroovy   1000000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation        1   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation       10   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation      100   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation     1000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation  1000000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface         1   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface        10   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface       100   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface      1000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface   1000000   avgt   15       ≈ 10⁻⁶
    ms/op


The benchmark code is available at this link
<https://github.com/apache/groovy/compare/master...pditommaso:jmh-list-equals-benchmark>.
These numbers suggest that checking the class annotation in the
`DefaultGroovyMethods.equals` method adds an overhead of ~5%, doing the
same with a marker interface ~10%.


What do you think ?


p



On Fri, Jan 26, 2018 at 3:21 PM, Paolo Di Tommaso <paolo.ditommaso@gmail.com
> wrote:

> I agree. The name @GroovyOverride sounds a good option.
>
>
>
> Cheers,
> Paolo
>
>
> On Thu, Jan 25, 2018 at 11:53 PM, MG <mg...@arscreat.com> wrote:
>
>> This looks like something that might be useful in certain scenarios. A
>> "perfect fix" would always be better, but since that might be some time off
>> (2019 being optimistic - some of the things I want Groovy to improve in
>> date back to at least 2006)...
>>
>> My only question would be, if it would perhaps make sense to introduce a
>> more generically named annotation (@AutomatismOverride, @GroovyOverride,
>> @Configuration,...), that would allow overriding/fine-tuning many of
>> Groovy's automatisms through different parameters, to avoid an
>> annotation-explosion over time ?
>>
>> mg
>>
>>
>> On 23.01.2018 09:25, Paolo Di Tommaso wrote:
>>
>> Hi all,
>>
>> I want to take the opportunity to renew my proposal and PR to add an
>> annotation that allows the override of the Groovy default formatting for
>> certain classes.
>>
>> https://github.com/apache/groovy/pull/566
>>
>>
>> To quickly remind you what the problem is, Groovy provides a nice default
>> formatting for some classes i.e. String, Map, and Collection data
>> structures which is good. But it makes impossible to override it by
>> sub-classes that implements their own toString method. The same problem for
>> the `equals` method. This makes difficult to handle some specific use
>> cases, leaving bytecode manipulation as the only alternative.
>>
>>
>> My proposal is to add an annotation named @IgnoreDefaultEqualsAndToString
>> (or maybe @OverrideEqualsAndToString) to bypass the Groovy formatting and
>> allow the invocation of sub-classes `toString` and `equals` methods.
>>
>> I agree that's a sub-optional solution, however no better solutions have
>> been proposed for the current and future releases.
>>
>>
>>
>> Cheers,
>> Paolo
>>
>>
>>
>> On Sun, Jun 25, 2017 at 8:35 PM, Paolo Di Tommaso <
>> paolo.ditommaso@gmail.com> wrote:
>>
>>> Dear all,
>>>
>>> Groovy still does not provide a mechanism to override the `toString` and
>>> `equals` methods for custom Collection and Map objects. This is a serious
>>> limitation in some use cases.
>>>
>>> I'm proposing with the following pull request to introduce a marker
>>> annotation that allows a custom object to use the `toString` and `equals`
>>> as expected.
>>>
>>> https://github.com/apache/groovy/pull/566
>>>
>>>
>>> Any comment or improvement is welcome.
>>>
>>>
>>> Cheers,
>>> Paolo
>>>
>>>
>>> On Thu, Jun 2, 2016 at 1:38 AM, Paul King <pa...@asert.com.au> wrote:
>>>
>>>> I am +1 on improving how we handle formatting for lists and maps. My
>>>> default position would be -1 on an implementation that smells like it
>>>> might be "yet another hack" that we have to maintain long term. The
>>>> main reason being that we are trying to streamline method selection
>>>> for our revised MOP (I know not much is happening in that space right
>>>> now) and it would be nicer if once that is done, the "inconsistent"
>>>> results you mention could be handled in an easy to understand way.
>>>> Having said that, if I get time to look into it further and can't
>>>> think of a better way to approach it long term, then I could easily be
>>>> moved to at least a -0.
>>>>
>>>> Cheers, Paul.
>>>>
>>>> On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
>>>> <pa...@gmail.com> wrote:
>>>> > Hello guys,
>>>> >
>>>> > No feedback on this? Would you take in consideration a PR for this
>>>> proposal?
>>>> >
>>>> >
>>>> > Thanks,
>>>> > Paolo
>>>> >
>>>> >
>>>> > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
>>>> > <pa...@gmail.com> wrote:
>>>> >>
>>>> >> Hi all,
>>>> >>
>>>> >> Groovy implements a built-in formatting strategy for collection and
>>>> map
>>>> >> objects that is surely nicer and more useful than the one provided
>>>> by the
>>>> >> default Java implementation for these classes.
>>>> >>
>>>> >> However there are use cases in which custom collection or map
>>>> classes need
>>>> >> to implement their own formatting rule.
>>>> >>
>>>> >> Currently in Groovy this is quite painful and may lead to
>>>> inconsistent
>>>> >> results. Take in consideration the following example:
>>>> >>
>>>> >> class MyList extends ArrayList {
>>>> >>  String toString() {
>>>> >>     this.join('-')
>>>> >>   }
>>>> >> }
>>>> >>
>>>> >> def x = new MyList()
>>>> >> x << 1 << 2 << 3
>>>> >>
>>>> >> println x.toString()
>>>> >> println x
>>>> >> println "$x"
>>>> >>
>>>> >> Which prints:
>>>> >>
>>>> >> 1-2-3
>>>> >> [1, 2, 3]
>>>> >> [1, 2, 3]
>>>> >>
>>>> >> Both the second and third `println` use the Groovy built-in
>>>> formatting
>>>> >> method and there's no easy way to override this behaviour. Also
>>>> there's not
>>>> >> a clear reason why the first and the second print return a different
>>>> output.
>>>> >>
>>>> >> The only options I've found is to define `MyList` with a @Delegate
>>>> without
>>>> >> implementing the `List` interface. But this leads to other weird side
>>>> >> effects. The remaining possibility is to use some bytecode
>>>> manipulation to
>>>> >> bypass the default Groovy formatting, but it looks to me a really
>>>> >> overkilling solution for such problem.
>>>> >>
>>>> >> For this reason a would like to propose to introduce a mechanism that
>>>> >> would allow custom collection and map classes to bypass the default
>>>> >> formatting method. This should not be too difficult. The current
>>>> Groovy
>>>> >> built-in formatting is implemented by formatList and formatMap
>>>> methods.
>>>> >>
>>>> >> It would be enough to add a marker interface (or an annotation) that
>>>> when
>>>> >> applied to a class it would be used to by-pass the logic in the
>>>> formatList
>>>> >> and formatMap methods and simply return the string provided by the
>>>> object
>>>> >> `toString` method.
>>>> >>
>>>> >>
>>>> >> I could easily contribute this patch however I would know the
>>>> opinion of
>>>> >> the Groovy core committers. In particular:
>>>> >>
>>>> >> 1) What name should have this marker interface?
>>>> groovy.lagn.Something?
>>>> >> 2) Are formatList and formatMap methods the right place to add this
>>>> logic?
>>>> >> 3) A similar problem exists also when using the `equals` (and
>>>> hashCode?)
>>>> >> method for collections and maps. Should this mechanism be extended
>>>> also to
>>>> >> this case?
>>>> >>
>>>> >>
>>>> >>
>>>> >> Best,
>>>> >> Paolo
>>>> >>
>>>> >>
>>>> >
>>>>
>>>
>>>
>>
>>
>

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paolo Di Tommaso <pa...@gmail.com>.
I agree. The name @GroovyOverride sounds a good option.



Cheers,
Paolo


On Thu, Jan 25, 2018 at 11:53 PM, MG <mg...@arscreat.com> wrote:

> This looks like something that might be useful in certain scenarios. A
> "perfect fix" would always be better, but since that might be some time off
> (2019 being optimistic - some of the things I want Groovy to improve in
> date back to at least 2006)...
>
> My only question would be, if it would perhaps make sense to introduce a
> more generically named annotation (@AutomatismOverride, @GroovyOverride,
> @Configuration,...), that would allow overriding/fine-tuning many of
> Groovy's automatisms through different parameters, to avoid an
> annotation-explosion over time ?
>
> mg
>
>
> On 23.01.2018 09:25, Paolo Di Tommaso wrote:
>
> Hi all,
>
> I want to take the opportunity to renew my proposal and PR to add an
> annotation that allows the override of the Groovy default formatting for
> certain classes.
>
> https://github.com/apache/groovy/pull/566
>
>
> To quickly remind you what the problem is, Groovy provides a nice default
> formatting for some classes i.e. String, Map, and Collection data
> structures which is good. But it makes impossible to override it by
> sub-classes that implements their own toString method. The same problem for
> the `equals` method. This makes difficult to handle some specific use
> cases, leaving bytecode manipulation as the only alternative.
>
>
> My proposal is to add an annotation named @IgnoreDefaultEqualsAndToString
> (or maybe @OverrideEqualsAndToString) to bypass the Groovy formatting and
> allow the invocation of sub-classes `toString` and `equals` methods.
>
> I agree that's a sub-optional solution, however no better solutions have
> been proposed for the current and future releases.
>
>
>
> Cheers,
> Paolo
>
>
>
> On Sun, Jun 25, 2017 at 8:35 PM, Paolo Di Tommaso <
> paolo.ditommaso@gmail.com> wrote:
>
>> Dear all,
>>
>> Groovy still does not provide a mechanism to override the `toString` and
>> `equals` methods for custom Collection and Map objects. This is a serious
>> limitation in some use cases.
>>
>> I'm proposing with the following pull request to introduce a marker
>> annotation that allows a custom object to use the `toString` and `equals`
>> as expected.
>>
>> https://github.com/apache/groovy/pull/566
>>
>>
>> Any comment or improvement is welcome.
>>
>>
>> Cheers,
>> Paolo
>>
>>
>> On Thu, Jun 2, 2016 at 1:38 AM, Paul King <pa...@asert.com.au> wrote:
>>
>>> I am +1 on improving how we handle formatting for lists and maps. My
>>> default position would be -1 on an implementation that smells like it
>>> might be "yet another hack" that we have to maintain long term. The
>>> main reason being that we are trying to streamline method selection
>>> for our revised MOP (I know not much is happening in that space right
>>> now) and it would be nicer if once that is done, the "inconsistent"
>>> results you mention could be handled in an easy to understand way.
>>> Having said that, if I get time to look into it further and can't
>>> think of a better way to approach it long term, then I could easily be
>>> moved to at least a -0.
>>>
>>> Cheers, Paul.
>>>
>>> On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
>>> <pa...@gmail.com> wrote:
>>> > Hello guys,
>>> >
>>> > No feedback on this? Would you take in consideration a PR for this
>>> proposal?
>>> >
>>> >
>>> > Thanks,
>>> > Paolo
>>> >
>>> >
>>> > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
>>> > <pa...@gmail.com> wrote:
>>> >>
>>> >> Hi all,
>>> >>
>>> >> Groovy implements a built-in formatting strategy for collection and
>>> map
>>> >> objects that is surely nicer and more useful than the one provided by
>>> the
>>> >> default Java implementation for these classes.
>>> >>
>>> >> However there are use cases in which custom collection or map classes
>>> need
>>> >> to implement their own formatting rule.
>>> >>
>>> >> Currently in Groovy this is quite painful and may lead to inconsistent
>>> >> results. Take in consideration the following example:
>>> >>
>>> >> class MyList extends ArrayList {
>>> >>  String toString() {
>>> >>     this.join('-')
>>> >>   }
>>> >> }
>>> >>
>>> >> def x = new MyList()
>>> >> x << 1 << 2 << 3
>>> >>
>>> >> println x.toString()
>>> >> println x
>>> >> println "$x"
>>> >>
>>> >> Which prints:
>>> >>
>>> >> 1-2-3
>>> >> [1, 2, 3]
>>> >> [1, 2, 3]
>>> >>
>>> >> Both the second and third `println` use the Groovy built-in formatting
>>> >> method and there's no easy way to override this behaviour. Also
>>> there's not
>>> >> a clear reason why the first and the second print return a different
>>> output.
>>> >>
>>> >> The only options I've found is to define `MyList` with a @Delegate
>>> without
>>> >> implementing the `List` interface. But this leads to other weird side
>>> >> effects. The remaining possibility is to use some bytecode
>>> manipulation to
>>> >> bypass the default Groovy formatting, but it looks to me a really
>>> >> overkilling solution for such problem.
>>> >>
>>> >> For this reason a would like to propose to introduce a mechanism that
>>> >> would allow custom collection and map classes to bypass the default
>>> >> formatting method. This should not be too difficult. The current
>>> Groovy
>>> >> built-in formatting is implemented by formatList and formatMap
>>> methods.
>>> >>
>>> >> It would be enough to add a marker interface (or an annotation) that
>>> when
>>> >> applied to a class it would be used to by-pass the logic in the
>>> formatList
>>> >> and formatMap methods and simply return the string provided by the
>>> object
>>> >> `toString` method.
>>> >>
>>> >>
>>> >> I could easily contribute this patch however I would know the opinion
>>> of
>>> >> the Groovy core committers. In particular:
>>> >>
>>> >> 1) What name should have this marker interface? groovy.lagn.Something?
>>> >> 2) Are formatList and formatMap methods the right place to add this
>>> logic?
>>> >> 3) A similar problem exists also when using the `equals` (and
>>> hashCode?)
>>> >> method for collections and maps. Should this mechanism be extended
>>> also to
>>> >> this case?
>>> >>
>>> >>
>>> >>
>>> >> Best,
>>> >> Paolo
>>> >>
>>> >>
>>> >
>>>
>>
>>
>
>

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by MG <mg...@arscreat.com>.
This looks like something that might be useful in certain scenarios. A 
"perfect fix" would always be better, but since that might be some time 
off (2019 being optimistic - some of the things I want Groovy to improve 
in date back to at least 2006)...

My only question would be, if it would perhaps make sense to introduce a 
more generically named annotation (@AutomatismOverride, @GroovyOverride, 
@Configuration,...), that would allow overriding/fine-tuning many of 
Groovy's automatisms through different parameters, to avoid an 
annotation-explosion over time ?

mg

On 23.01.2018 09:25, Paolo Di Tommaso wrote:
> Hi all,
>
> I want to take the opportunity to renew my proposal and PR to add an 
> annotation that allows the override of the Groovy default formatting 
> for certain classes.
>
> https://github.com/apache/groovy/pull/566
>
>
> To quickly remind you what the problem is, Groovy provides a nice 
> default formatting for some classes i.e. String, Map, and Collection 
> data structures which is good. But it makes impossible to override it 
> by sub-classes that implements their own toString method. The same 
> problem for the `equals` method. This makes difficult to handle some 
> specific use cases, leaving bytecode manipulation as the only alternative.
>
>
> My proposal is to add an annotation named 
> @IgnoreDefaultEqualsAndToString (or maybe @OverrideEqualsAndToString) 
> to bypass the Groovy formatting and allow the invocation of 
> sub-classes `toString` and `equals` methods.
>
> I agree that's a sub-optional solution, however no better solutions 
> have been proposed for the current and future releases.
>
>
>
> Cheers,
> Paolo
>
>
> On Sun, Jun 25, 2017 at 8:35 PM, Paolo Di Tommaso 
> <paolo.ditommaso@gmail.com <ma...@gmail.com>> wrote:
>
>     Dear all,
>
>     Groovy still does not provide a mechanism to override the
>     `toString` and `equals` methods for custom Collection and Map
>     objects. This is a serious limitation in some use cases.
>
>     I'm proposing with the following pull request to introduce a
>     marker annotation that allows a custom object to use the
>     `toString` and `equals` as expected.
>
>     https://github.com/apache/groovy/pull/566
>     <https://github.com/apache/groovy/pull/566>
>
>
>     Any comment or improvement is welcome.
>
>
>     Cheers,
>     Paolo
>
>
>     On Thu, Jun 2, 2016 at 1:38 AM, Paul King <paulk@asert.com.au
>     <ma...@asert.com.au>> wrote:
>
>         I am +1 on improving how we handle formatting for lists and
>         maps. My
>         default position would be -1 on an implementation that smells
>         like it
>         might be "yet another hack" that we have to maintain long
>         term. The
>         main reason being that we are trying to streamline method
>         selection
>         for our revised MOP (I know not much is happening in that
>         space right
>         now) and it would be nicer if once that is done, the
>         "inconsistent"
>         results you mention could be handled in an easy to understand way.
>         Having said that, if I get time to look into it further and can't
>         think of a better way to approach it long term, then I could
>         easily be
>         moved to at least a -0.
>
>         Cheers, Paul.
>
>         On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
>         <paolo.ditommaso@gmail.com <ma...@gmail.com>>
>         wrote:
>         > Hello guys,
>         >
>         > No feedback on this? Would you take in consideration a PR
>         for this proposal?
>         >
>         >
>         > Thanks,
>         > Paolo
>         >
>         >
>         > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
>         > <paolo.ditommaso@gmail.com
>         <ma...@gmail.com>> wrote:
>         >>
>         >> Hi all,
>         >>
>         >> Groovy implements a built-in formatting strategy for
>         collection and map
>         >> objects that is surely nicer and more useful than the one
>         provided by the
>         >> default Java implementation for these classes.
>         >>
>         >> However there are use cases in which custom collection or
>         map classes need
>         >> to implement their own formatting rule.
>         >>
>         >> Currently in Groovy this is quite painful and may lead to
>         inconsistent
>         >> results. Take in consideration the following example:
>         >>
>         >> class MyList extends ArrayList {
>         >>  String toString() {
>         >>     this.join('-')
>         >>   }
>         >> }
>         >>
>         >> def x = new MyList()
>         >> x << 1 << 2 << 3
>         >>
>         >> println x.toString()
>         >> println x
>         >> println "$x"
>         >>
>         >> Which prints:
>         >>
>         >> 1-2-3
>         >> [1, 2, 3]
>         >> [1, 2, 3]
>         >>
>         >> Both the second and third `println` use the Groovy built-in
>         formatting
>         >> method and there's no easy way to override this behaviour.
>         Also there's not
>         >> a clear reason why the first and the second print return a
>         different output.
>         >>
>         >> The only options I've found is to define `MyList` with a
>         @Delegate without
>         >> implementing the `List` interface. But this leads to other
>         weird side
>         >> effects. The remaining possibility is to use some bytecode
>         manipulation to
>         >> bypass the default Groovy formatting, but it looks to me a
>         really
>         >> overkilling solution for such problem.
>         >>
>         >> For this reason a would like to propose to introduce a
>         mechanism that
>         >> would allow custom collection and map classes to bypass the
>         default
>         >> formatting method. This should not be too difficult. The
>         current Groovy
>         >> built-in formatting is implemented by formatList and
>         formatMap methods.
>         >>
>         >> It would be enough to add a marker interface (or an
>         annotation) that when
>         >> applied to a class it would be used to by-pass the logic in
>         the formatList
>         >> and formatMap methods and simply return the string provided
>         by the object
>         >> `toString` method.
>         >>
>         >>
>         >> I could easily contribute this patch however I would know
>         the opinion of
>         >> the Groovy core committers. In particular:
>         >>
>         >> 1) What name should have this marker interface?
>         groovy.lagn.Something?
>         >> 2) Are formatList and formatMap methods the right place to
>         add this logic?
>         >> 3) A similar problem exists also when using the `equals`
>         (and hashCode?)
>         >> method for collections and maps. Should this mechanism be
>         extended also to
>         >> this case?
>         >>
>         >>
>         >>
>         >> Best,
>         >> Paolo
>         >>
>         >>
>         >
>
>
>


Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paolo Di Tommaso <pa...@gmail.com>.
Hi all,

I want to take the opportunity to renew my proposal and PR to add an
annotation that allows the override of the Groovy default formatting for
certain classes.

https://github.com/apache/groovy/pull/566


To quickly remind you what the problem is, Groovy provides a nice default
formatting for some classes i.e. String, Map, and Collection data
structures which is good. But it makes impossible to override it by
sub-classes that implements their own toString method. The same problem for
the `equals` method. This makes difficult to handle some specific use
cases, leaving bytecode manipulation as the only alternative.


My proposal is to add an annotation named @IgnoreDefaultEqualsAndToString
(or maybe @OverrideEqualsAndToString) to bypass the Groovy formatting and
allow the invocation of sub-classes `toString` and `equals` methods.

I agree that's a sub-optional solution, however no better solutions have
been proposed for the current and future releases.



Cheers,
Paolo



On Sun, Jun 25, 2017 at 8:35 PM, Paolo Di Tommaso <paolo.ditommaso@gmail.com
> wrote:

> Dear all,
>
> Groovy still does not provide a mechanism to override the `toString` and
> `equals` methods for custom Collection and Map objects. This is a serious
> limitation in some use cases.
>
> I'm proposing with the following pull request to introduce a marker
> annotation that allows a custom object to use the `toString` and `equals`
> as expected.
>
> https://github.com/apache/groovy/pull/566
>
>
> Any comment or improvement is welcome.
>
>
> Cheers,
> Paolo
>
>
> On Thu, Jun 2, 2016 at 1:38 AM, Paul King <pa...@asert.com.au> wrote:
>
>> I am +1 on improving how we handle formatting for lists and maps. My
>> default position would be -1 on an implementation that smells like it
>> might be "yet another hack" that we have to maintain long term. The
>> main reason being that we are trying to streamline method selection
>> for our revised MOP (I know not much is happening in that space right
>> now) and it would be nicer if once that is done, the "inconsistent"
>> results you mention could be handled in an easy to understand way.
>> Having said that, if I get time to look into it further and can't
>> think of a better way to approach it long term, then I could easily be
>> moved to at least a -0.
>>
>> Cheers, Paul.
>>
>> On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
>> <pa...@gmail.com> wrote:
>> > Hello guys,
>> >
>> > No feedback on this? Would you take in consideration a PR for this
>> proposal?
>> >
>> >
>> > Thanks,
>> > Paolo
>> >
>> >
>> > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
>> > <pa...@gmail.com> wrote:
>> >>
>> >> Hi all,
>> >>
>> >> Groovy implements a built-in formatting strategy for collection and map
>> >> objects that is surely nicer and more useful than the one provided by
>> the
>> >> default Java implementation for these classes.
>> >>
>> >> However there are use cases in which custom collection or map classes
>> need
>> >> to implement their own formatting rule.
>> >>
>> >> Currently in Groovy this is quite painful and may lead to inconsistent
>> >> results. Take in consideration the following example:
>> >>
>> >> class MyList extends ArrayList {
>> >>  String toString() {
>> >>     this.join('-')
>> >>   }
>> >> }
>> >>
>> >> def x = new MyList()
>> >> x << 1 << 2 << 3
>> >>
>> >> println x.toString()
>> >> println x
>> >> println "$x"
>> >>
>> >> Which prints:
>> >>
>> >> 1-2-3
>> >> [1, 2, 3]
>> >> [1, 2, 3]
>> >>
>> >> Both the second and third `println` use the Groovy built-in formatting
>> >> method and there's no easy way to override this behaviour. Also
>> there's not
>> >> a clear reason why the first and the second print return a different
>> output.
>> >>
>> >> The only options I've found is to define `MyList` with a @Delegate
>> without
>> >> implementing the `List` interface. But this leads to other weird side
>> >> effects. The remaining possibility is to use some bytecode
>> manipulation to
>> >> bypass the default Groovy formatting, but it looks to me a really
>> >> overkilling solution for such problem.
>> >>
>> >> For this reason a would like to propose to introduce a mechanism that
>> >> would allow custom collection and map classes to bypass the default
>> >> formatting method. This should not be too difficult. The current Groovy
>> >> built-in formatting is implemented by formatList and formatMap methods.
>> >>
>> >> It would be enough to add a marker interface (or an annotation) that
>> when
>> >> applied to a class it would be used to by-pass the logic in the
>> formatList
>> >> and formatMap methods and simply return the string provided by the
>> object
>> >> `toString` method.
>> >>
>> >>
>> >> I could easily contribute this patch however I would know the opinion
>> of
>> >> the Groovy core committers. In particular:
>> >>
>> >> 1) What name should have this marker interface? groovy.lagn.Something?
>> >> 2) Are formatList and formatMap methods the right place to add this
>> logic?
>> >> 3) A similar problem exists also when using the `equals` (and
>> hashCode?)
>> >> method for collections and maps. Should this mechanism be extended
>> also to
>> >> this case?
>> >>
>> >>
>> >>
>> >> Best,
>> >> Paolo
>> >>
>> >>
>> >
>>
>
>