Hi Daniel,
another flag from me: If I understand you correctly, you want to change
existing GString literal semantics to make it work as if toString() had
implicitely on it; i.e. there would be no more GString literal, but
instead String interpolation support for regular String literals in
double quotes ?
This would be a framework breaking change for me, since I am using the
GString feature to be able to access a GString's embedded objects
extensively in my SQL building framework.
Simple example:
String category = "HEAD"
final Table pe = Table.reference(PERSON)
final Table org = Table.reference(ORG_TREE)
GString sql = """
select $pe.ID, $pe.FIRST_NAME, $pe.LAST_NAME, $org.DEPARTMENT
from $pe, $org
where
$pe.ORG_ID = $org.ID and $org.CATEGORY = ${BindValue.val(category)}
"""
sql = tableToViewSubstitution(sql) // Replace some table instances with
their View equivalent
sql = renumberReferenceNames(sql) // Iterates over sql.objects,
modifying embedded Table/Column/View/... objects from my framework
SqlExecutor.create(...).rows(sql) // Convert passed sql GString into
Groovy Sql compatible GString
How is the proposed change expected to work with existing Groovy Sql
support for implicitly interpreting embedded objects as bind values
(since this is too restrictive/inflexible for heavy use I have changed
this from implicit to explicit support (BindValue class) in my framework).
Cheers,
mg
On 08.09.2018 03:07, Daniel.Sun wrote:
Hi all,
In most of cases, we just use GString as an enhanced String, but
currently GString is not implemented eager so it has some weird features,
which will confuse users. Let's look at some examples[1] from Jochen:
* the referenced variables are bound eager
* toString on GString evaluates the GString, this includes toString for the
values
```
def x = 1
def gstring = "$x"
assert gstring == "1"
x = 2
assert gstring == "1"
```
```
class X {
int i = 0
String toString(){Integer.toString(i++)}
}
def x = new X()
def gstring = "$x"
assert gstring == "0"
assert gstring == "1" // the content of gstring changed...
```
If we implement GString eager and treated as normal String(not expose
GString API), the content of GString will not change once it is evaluated.
We can get the following benefits:
1) Users will not be confused because of some weird feature;
2) Better compatibility between dynamic and static compilation, SEE
GROOVY-6668[1];
3) The performance will be improved to some extent because GString will not
be evaluated again and again even if its content is not changed;
The proposal is a breaking change, so I propose it is targeted to
groovy 3.0.0 if accepted.
P.S. some issues like GROOVY-6668 are raised by users again and again, that
is say, many users are confused by current implementation, i.e. GString can
not be treated as normal String in STC. In the static compilation mode:
```
@groovy.transform.CompileStatic
class Test {
static void main(String[] args) {
def m = ['a':1, 'b':2]
def k = 'a'
assert 1 == m[k]
assert 1 == m["$k" as String]
assert 1 == m["$k"] // fails, gets null, which is not equal to 1
}
}
```
Cheers,
Daniel.Sun
[1] https://github.com/apache/groovy/pull/708
-----
Daniel Sun
Apache Groovy committer
Blog: http://blog.sunlan.me
Twitter: @daniel_sun
--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html