Scott Murphy Heiberg created GROOVY-12578:
---------------------------------------------

             Summary: A closure's own method runs twice when neither the 
delegate nor the owner can take the call
                 Key: GROOVY-12578
                 URL: https://issues.apache.org/jira/browse/GROOVY-12578
             Project: Groovy
          Issue Type: Bug
          Components: groovy-runtime
    Affects Versions: 6.0.0
            Reporter: Scott Murphy Heiberg


For an implicit-this call in a closure body to a method the closure inherits, 
such as {{toString()}} or a default Groovy method like {{with}}, {{tap}} or 
{{identity}}, {{ClosureMetaClass}} tries the delegate and the owner first and 
keeps the closure's own method as the fallback. When neither can take the call, 
it invokes the fallback, discards the result and throws 
{{MissingMethodException}}; invokedynamic catches it and calls the method again 
through {{GroovyObject.invokeMethod}}, so the method runs twice:

{code:groovy}
class C { Closure<Integer> withCount() { { -> int n = 0; with { n++ }; n } } }
Closure<Integer> c = new C().withCount().rehydrate(null, null, null)
c.resolveStrategy = Closure.OWNER_ONLY
assert c() == 1 // 2
{code}

Called through the meta class directly ({{c.metaClass.invokeMethod(...)}}), the 
call throws {{MissingMethodException}} after running the method. A closure 
without an owner and with {{OWNER_ONLY}}, or with {{DELEGATE_ONLY}} and no 
delegate, reaches the fallback. Expected: the fallback's result is returned.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to