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

Jim Klimov edited comment on GROOVY-11059 at 5/18/23 8:07 AM:
--------------------------------------------------------------

Regarding comparisons, I think currently the {{isCase()}} is also loosely 
useful, given that it would have to be defined in (or hacked into) third-party 
classes to compare with our custom classes. I mean use-cases like:
{code:java}
MyClass val = ... // implements equals() and/or compareTo() which do work for 
strings/numbers/... when called directly

switch (val) {
    case "SomeString": // needs a String.asType() implementation, code in 
MyClass is not called
    case 0: // needs a Integer(?).asType() implementation, code in MyClass is 
not called
}{code}
One simple case I had in mind was a class to wrap the return value of a "sh" 
step in Jenkins (calling an external shell program) which may return an 
exit-code and/or stdout of that program (further code jumps through hoops to 
collect both). My custom class has fields to store either (or both), and its 
comparison/equality methods check against one or the other depending on the 
counterpart data type (numbers to exit-codes, strings to stdout).

Original code in the pipelines used {{def res = sh (...)}} so the {{res}} ended 
up as an {{Integer}} or {{String}} depending on parameters of {{sh()}} and 
comparisons, switch/case, "in [some, list]" etc. operations were easy. With a 
wrapper that makes-believe it is a string or integer depending on context it 
is... not really sure if possible currently? (I mean, direct field comparisons 
like {{if (newRes.status in [1, 2, 3])}} or {{switch(newRes.getStdout())...}} 
are surely possible, but would require changes across the board so are not an 
"easy" fix, and would make the consumer code more intimately tied to the data 
type used)


was (Author: JIRAUSER300415):
Regarding comparisons, I think currently the {{isCase()}} is also loosely 
useful, given that it would have to be defined in (or hacked into) third-party 
classes to compare with our custom classes. I mean use-cases like:
{code:java}
MyClass val = ... // implements equals() and/or compareTo() which do work for 
strings/numbers/... when called directly

switch (val) {
    case "SomeString": // needs a String.asType() implementation, code in 
MyClass is not called
    case 0: // needs a Integer(?).asType() implementation, code in MyClass is 
not called
}{code}
One simple case I had in mind was a class to wrap the return value of a "sh" 
step in Jenkins (calling an external shell program) which may return an 
exit-code and/or stdout of that program (further code jumps through hoops to 
collect both). My custom class has fields to store either (or both), and its 
comparison/equality methods check against one or the other depending on the 
counterpart data type (numbers to exit-codes, strings to stdout).

Original code in the pipelines used {{def res = sh (...)}} so the {{res}} ended 
up as an {{Integer}} or {{String}} depending on parameters of {{sh()}} and 
comparisons, switch/case, "in [some, list]" etc. operations were easy. With a 
wrapper that makes-believe it is a string or integer depending on context it 
is... not really sure if possible currently? (I mean, direct comparisons like 
{{newRes.status in [1, 2, 3]}} or {{switch(newRes.getStdout())...}} are surely 
possible, but would require changes across the board so are not an "easy" fix, 
and would make the consumer code more intimately tied to the data type used)

> Want a way to define casting/coercing FROM other classes as part of my class
> ----------------------------------------------------------------------------
>
>                 Key: GROOVY-11059
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11059
>             Project: Groovy
>          Issue Type: Wish
>            Reporter: Jim Klimov
>            Priority: Major
>
> Java has basic casting which relies on one object having a class/interface 
> which is descendant of another in the equation. Groovy extends this with 
> coercion which relies on the origin class defining an {{asType()}} method to 
> state how convert it into an instance of a target class.
> For example, if I want to assign my class from a standard {{String}} I'd have 
> to hack with metaclass of String to extend its {{asType}} to recognize 
> {{MyClass}} and coerce INTO it, and then I'd be able to say:
> {code:java}
> MyClass myval = "SomeString" as MyClass{code}
> This is clumsy both on implementation side (hacking into other people's code 
> is not too portable, and has complications with code that runs this hack many 
> times like a Jenkins Shared Library that would change server JVM's String 
> over and over for each run), and on coding side (while "as SomeClass" is 
> explicit, someone has to write it which adds noise in refactorings and goes 
> against the type simplicity trend of the language).
> My proposal is to support a common optional method everywhere, in the 
> groovyish manner of plastering so many other optional operator overloads like 
> {{{}asType(){}}}, {{{}isCase(){}}}, {{plus()}} et al, which would be 
> effectively an inverse {{asType()}} and overload the assignment operator.
> By default it could invoke single-parameter constructors (e.g. if I define a 
> {{MyClass(String)}} one - that can be used to cast the assignment from a 
> {{{}String{}}}), and it might be extensible if someone has more complex ideas 
> for their class (e.g. change something in the existing instance instead of 
> creating a new one, if the override is non-static, or if it generally gets a 
> parameter with an instance of this class and this parameter is null or not). 
> Either way, for script writers it would be just a simple assignment symbol 
> with smarts behind the curtain.
> Possibly this might fill in the gap of current {{equals()}} overload that did 
> not always work well for me (possibly due to ancient groovy in Jenkins core) 
> to check {{{}if (myClassVal == "somestring") {...{}}}}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to