[ https://issues.apache.org/jira/browse/GROOVY-11211?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17781764#comment-17781764 ]
Eric Milles edited comment on GROOVY-11211 at 11/1/23 2:52 PM: --------------------------------------------------------------- There was a change in Groovy 4 affecting the order of resolution. Providing a generic property resolver method like Map's {{get(K)}} and a method invocation resolver like {{invokeMethod}} or {{methodMissing}} might need some fine tuning. Map to type coercion for reference: https://docs.groovy-lang.org/latest/html/documentation/#_map_to_type_coercion was (Author: emilles): There was a change in Groovy 4 affecting the order of resolution. Providing a generic property resolver method like Map's {{get(K)}} and a method invocation resolver like {{invokeMethod}} or {{methodMissing}} might need some fine tuning. > Unexpected invocation of getter method > -------------------------------------- > > Key: GROOVY-11211 > URL: https://issues.apache.org/jira/browse/GROOVY-11211 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime > Affects Versions: 4.0.15 > Reporter: paolo di tommaso > Assignee: Eric Milles > Priority: Minor > > The map {{get}} method is invoked unexpectedly while resolving a closure > delegate. > To replicate the issue consider the following custom Map object in which both > {{get}} and {{invokeMethod}} methods are overridden: > {code:groovy} > class Context implements Map<String,Object> { > @Delegate private Map<String,Object> target > Context(Map<String,Object> target) { this.target = target } > @Override > Object get(Object name) { > if( target.containsKey(name) ) > return target.get(name) > throw new Exception('Missing key: ' + name) > } > @Override > Object invokeMethod(String name, Object args) { > if( name == 'foo' ) > return 'OK' > else > super.invokeMethod(name, args) > } > } > {code} > > Then, a closure tries to invoke the {{foo}} method via a context delegate, as > shown below: > {code:groovy} > def closure = { it -> foo() } > closure.delegate = new Context([:]) > closure.setResolveStrategy(Closure.DELEGATE_ONLY) > assert closure.call() == 'OK' > {code} > > The "OK" string should be returned by the closure because {{foo}} method > should be resolved via the {{invokeMethod}} method. > > However, the above snippet fails with the following message: > {code} > java.lang.Exception: Missing key: foo > {code} > > This code works as expected with Groovy 3.x -- This message was sent by Atlassian Jira (v8.20.10#820010)