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

Chaitanya Birudavolu edited comment on GROOVY-8952 at 1/9/19 12:02 PM:
-----------------------------------------------------------------------

[~blackdrag], I looked at the link you've pointed to, and it doesn't seem to 
cover the scenario I'm talking about. It talks about an eager placeholder 
*${<expression>}*, where the type of *<expression>* is not Closure. It also 
talks about the lazy placeholder *${->}*, which is surely not the same thing as 
an an eager placeholder enclosing an expression of type Closure.

(Can I just say PH instead of placeholder?).

Referring back to the code I posted, notice that I have an eager PH *${}*, 
enclosing an expression whose value is of type Closure. As per all 
documentation that I've seen so far, for any eager PH *${<expression>}*, what 
must eventually appear in the place of the PH is 
*<expression-value>.toString()*, where *<expression-value>* is the value of 
whatever is enclosed by the PH.

The problem which we are discussing however, is that when we have an *eager* PH 
*${}* and if the type of *<expression-value>* is GString, three things happen, 
all of which are surprises, and not documented:
 # An invocation of the closure is happening.
 # The invocation of the closure is happening lazily rather than eagerly, even 
though the PH enclosing *<expression>* is an *eager* one *${}* as in my code. 
For an eager PH *${}*, the substitution should happen eagerly, and what we 
finally get in the place of the PH should not depend upon when the GString 
coercion to String happens.
 # In the place of the PH, instead of the result of 
*<expression-value>.toString()*, what is actually appearing is the result of 
*<expression-value>.call().toString()*


was (Author: iamchaitanya):
[~blackdrag], I looked at the link you've pointed to, and it doesn't seem to 
cover the scenario I'm talking about. It talks about an eager placeholder 
*${<expression>}*, where the type of *<expression>* is not Closure. It also 
talks about the lazy placeholder *${->}*, which is surely not the same thing as 
an an eager placeholder enclosing an expression of type Closure.

(Can I just say PH instead of placeholder?).

Referring back to the code I posted, notice that I have an eager PH *${}*, 
enclosing an expression whose value is of type Closure. As per all 
documentation that I've seen so far, for any eager PH, what must eventually 
appear in the place of the PH is *<expression-value>.toString()*, where 
*<expression-value>* is the value of whatever is enclosed by the PH.

The problem which we are discussing however, is that when we have an *eager* PH 
*${}* and if the type of *<expression-value>* is GString, three things happen, 
all of which are surprises, and not documented:
 # An invocation of the closure is happening.
 # The invocation of the closure is happening lazily rather than eagerly, even 
though the PH enclosing *<expression>* is an *eager* one *${}* as in my code. 
For an eager PH *${}*, the substitution should happen eagerly, and what we 
finally get in the place of the PH should not depend upon when the GString 
coercion to String happens.
 # In the place of the PH, instead of the result of 
*<expression-value>.toString()*, what is actually appearing is the result of 
*<expression-value>.call().toString()*

> Eager interpolation evaluating as a Closure does a lazy invoke of the Closure
> -----------------------------------------------------------------------------
>
>                 Key: GROOVY-8952
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8952
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.5.5
>         Environment: Windows 10
>            Reporter: Chaitanya Birudavolu
>            Priority: Major
>              Labels: closure, eager, interpolation
>
> This is regarding the eager interpolation placeholder
> {code:java}
> ${ <expression> }{code}
> The expected behavior is that the expression would be evaluated eagerly (at 
> GString creation time). Later, at GString coercion time, the value that is 
> expected in the place of the eager placeholder is the result of
> {code:java}
> <expression>.toString(){code}
>  
>  
> This works most of the time, but doesn't seem to work if the expression 
> evaluates to a Closure type. If the expression evaluates to a Closure type, 
> what is observed is that, in the place of the placeholder, instead of seeing 
> ...
> {code:java}
> <closure>.toString(){code}
> ... we see...
> {code:java}
> <closure-invocation-result>.toString(){code}
> For example, in the below code...
>  
> {code:java}
> def c = {->println ('Inside closure')}
> println ('Just before creating the GString')
> def gstr = "${println ('Inside eager placeholder'); 20; 30; c}"
> println ('Just after creating the GString')
> println (gstr)
> {code}
>  
> ...the expected behavior is that the closure should never get executed, and 
> the last println should only print the result of
> {code:java}
> c.toString(){code}
> Instead, the last line printed is observed to be:
> {code:java}
> Inside closure{code}
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to