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

mgroovy commented on GROOVY-10259:
----------------------------------

* NameAndValue is a very small helper class that has 3 goals:
## Supply a practical/convenient default behavior for logging purposes when its 
toString method is called when the GString it will typically be embedded in 
gets converted to a String
## Support easy processing through standard Groovy 
string-interpolation/collect/join functionality to get custom string conversion 
behavior
## Support additional applications such as supplying the relevant properties of 
a class for one-source-of-truth, trait based hashCode/equals/compare/toString 
functionality
** all with a low overhead
* The existing classes you mention seem imho to be too far away from this 
functionality to replace NameAndValue with them
* Specifically with regards to NamedTuple: I have never had any case where I 
would have needed/wanted a map instead of a list for the name-value pairs

> Groovy4 NV Macros: Rename NV* -> SV*
> ------------------------------------
>
>                 Key: GROOVY-10259
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10259
>             Project: Groovy
>          Issue Type: Proposal
>    Affects Versions: 4.0.0-beta-1
>            Reporter: mgroovy
>            Priority: Major
>
> According to the release notes 
> ([https://groovy-lang.org/releasenotes/groovy-4.0.html]) "stringify" macros 
> will be released with Groovy 4, using a NV* naming convention.
> I propose to change the "stringify variable" macro names from
>  NV/NVI/NVD
>  to
>  SV/SVI/SVD
> Rationale:
>  * The planned Groovy4 NV macros immediately (G)Stringify their arguments, 
> always creating the same fixed textual representation (which cannot be 
> processed further in any meaningful way).
>  * NV is the macro name I originally proposed (and currently use), but it 
> returns a NameAndValue instance (see below for a slightly simplified version 
> of my in any case trivial NameAndValue class), instead of directly returning 
> a String representation
>  ** The NV macro name was chosen since it mirrors the name of the class it 
> creates, which holds the stringified expression ("name") that has been passed 
> to the NV macro, together with a reference to the result ("value") of 
> evaluating said expression, i.e. in the end holds a name together with a 
> value.
>  ** Note: A 2nd macro, NVL, in my implementation takes multiple arguments and 
> creates a list of NameAndValue objects, i.e. NVL(x0,x1,x2) === 
> [NV(x0),NV(x1),NV(x3)]
>  *** NV was kept to take only one argument, so additional arguments regarding 
> output formatting could be supported in the future.
>  * The returned NameAndValue objects can then be used flexibly to process 
> further to e.g. create regex expressions, XML, test output, etc (or log/print 
> directly if you like).
>  * Both approaches by default create the same output when converted into a 
> string, namely {code}NV(x) -> "x=$x"{code}
>  * The current Groovy4 variety trades flexibility for performance (no 
> intermediate NameAndValue objects are created), which is a good thing to have.
>  * However it blocks both concepts from coexisting while using a concise, 2 
> letter macro name.
> I therefore propose to change the naming convention of the Groovy 4 macros 
> from NV* to SV*, since it
>  # better expresses what happens ("stringify variable"), and
>  # allows for the name & value pairs of the (more flexible/powerful) NV* 
> macro and NameAndValue class to coexist with it.
> Basic NameAndValue class:
> {code:java}
> class NameAndValue<T> {
>       final String name
>       final T val
>       NameAndValue(String name, val) {
>        this.name = name
>        this.val = val
>       }
>       @Override
>       String toString() { 
>          "$name=$val"
>       }
> } 
> {code}
> NameAndValue class I actually use (with quote functionality):
> {code:java}
> class NameAndValue<T> {
>       final String name
>       final T val
>       static <T0> NameAndValue<T0> nava(String name, T0 val) {
>               new NameAndValue<T0>(name, val)
>       }
>       NameAndValue(String name, val) {
>               this.name = name
>               this.val = val
>       }
>       String quote(final Object o) {
>               if(null == o) {
>                       return null
>               }
>               else if(o instanceof GString) {
>                       return '"' + o + '"'
>               }
>               else if(o instanceof String) {
>                       return "'" + o + "'"
>               }
>               else if(o instanceof Character) {
>                       return "C'" + o + "'"
>               }
>               else {
>                       try {
>                               return o.toString()
>                       }
>                       catch(Throwable throwable0) {
>                               try {
>                                       return 
> "NV(${o.getClass().simpleName}.toString() threw 
> ${throwable0.getClass().simpleName})"
>                               }
>                               catch(Throwable throwable1) {
>                                       return "NV(o.getClass() threw 
> ${throwable1.getClass().simpleName})"
>                               }
>                       }
>               }
>       }
>       @Override
>       String toString() {
>          "$name=${quote(val)}"
>       }
> }
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to