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

Jochen Theodorou commented on GROOVY-11313:
-------------------------------------------

[~emilles] Looks like I forgot to make an example with owner comming from 
another closure:
{code:Java}
def cl = { owner -> {return {owner}}}
assert cl(1)() == 1
{code}
The inner owner reference is not supposed to be resolved against the owner 
getter of the outer closure, not even if owner comes from more outside, as long 
as owner is a local variable. And of course I also expect this to work 
(independent of the resolving strategy):
{code:Java}
def foo = 'bar'
def cl = { return {return {foo}}}
assert cl(1)() == foo
{code}
There should be no getter created for foo, since foo is a context variable 
encapsulated in a holder, given to the closure at construction time. Therefore 
I do not understand the change you did for this. But that is not your fault - I 
see those getter actually exist for a longer time already. But really they 
should not, exactly because of the name clash. There cannot be a getOwner 
method for owner as property of the Closure and for owner as referenced local 
variable. Either those getter are required, then this name clash is a problem 
and your fix is probably a good temporary solution... or the getter are not 
required, then we should not create them.



> Closure owner seems to be overwritten
> -------------------------------------
>
>                 Key: GROOVY-11313
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11313
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 4.0.18
>            Reporter: Tomás Crespo García
>            Assignee: Eric Milles
>            Priority: Major
>             Fix For: 3.0.21, 4.0.19, 5.0.0-alpha-6
>
>
> I had a Groovy script with nested closures that used {{owner}} as the name of 
> the outer closure's parameter (even though {{owner}} might conflict with the 
> closure [owner|https://groovy-lang.org/closures.html#_owner_of_a_closure]):
> {code:java}
> import groovy.sql.GroovyRowResult
>  
> runAll()
>  
> void runAll() {
>     List owners = [new GroovyRowResult([user_id: 1])]
>     List pets = [new GroovyRowResult([id: 1])]
>  
>     owners.each { owner ->
>         myMethod(1)
>         pets.each { pet ->
>             myMethod(2)
>             println(owner.user_id)
>         }
>     }
> }
>  
> void myMethod(int i) {
>     println("Running my method ${i}")
> } {code}
> The same script worked as I expected in Groovy 3.x, but, in Groovy 4.0.18, it 
> fails with the following error:
> {code:java}
> Exception in thread "main" groovy.lang.MissingPropertyException: No such 
> property: myMethod for class: groovy.sql.GroovyRowResult
> at groovy.sql.GroovyRowResult.getProperty(GroovyRowResult.java:55)
> at groovy.sql.GroovyRowResult.get(GroovyRowResult.java:157)
> at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1389)
> at groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1335)
> at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
> at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
> at 
> org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:645)
> at 
> org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
> at 
> org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObjects(ClosureMetaClass.java:391)
> at 
> org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:328)
> at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
> at 
> org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
> at Script1$_runAll_closure1$_closure2.doCall(Script1.groovy:16)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
> Method)
> at 
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
> at 
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.base/java.lang.reflect.Method.invoke(Method.java:568)
> at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
> at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328) {code}
> It seems that {{myMethod}} in the inner closure is trying to get resolved as 
> a property of {{{}GroovyRowResult{}}}, which is the type of the {{owner}} 
> parameter of the outer closure. The moment I rename {{owner}} to something 
> else or transform the inner {{each}} to a {{for}} loop, the script works. It 
> doesn't fail either if I don't try to access any property of {{owner}} inside 
> the inner closure (such as {{{}owner.user_id{}}}).
>  
> Is this expected? 
>  



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

Reply via email to