[
https://issues.apache.org/jira/browse/GROOVY-12664?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Scott Murphy Heiberg updated GROOVY-12664:
------------------------------------------
Affects Version/s: (was: 7.0.0-alpha-1)
> Implicit-this call to an Object extension method inside a closure runs twice
> when delegate and owner cannot take it
> -------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12664
> URL: https://issues.apache.org/jira/browse/GROOVY-12664
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> {code:groovy}
> int count = 0
> def c = { -> with { ++count } }
> c.resolveStrategy = Closure.DELEGATE_ONLY
> c.delegate = null
> def result = c()
> println "result=$result count=$count"
> {code}
> *Actual* (6.0.0 and master): {{result=2 count=2}}. The {{with}} block runs
> twice. Calling the metaclass directly, as
> {{c.metaClass.invokeMethod(this.getClass(), c, 'sprintf', ['%d', 42] as
> Object[], false, true)}}, throws MissingMethodException.
> *Expected* (as in 4.0.33 and 5.0.8): {{result=1 count=1}}, and the direct
> metaclass call returns "42".
> The same happens with a delegate that is the closure itself, after
> dehydrate() with DELEGATE_ONLY, after rehydrate(null, null, null) with
> OWNER_ONLY, and with @TypeChecked.
> Cause: GROOVY-11858 made {{ClosureMetaClass.invokeMethod}} defer a
> non-closure method so that delegate and owner are tried first. When neither
> can take the call, the deferred method is invoked but its result is not
> returned, and MissingMethodException is thrown. The indy fallback then
> retries through GroovyObject.invokeMethod and calls the method again.
> Verified: 6.0.0 and master affected; 4.0.33 and 5.0.8 not affected.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)