Dear community,

After switching to Groovy 4, I've observed an expected invocation of the
Map get method while resolving a closure delegate context.

Consider the following custom Map object in which both `get` and
`invokeMethod` methods are overridden:

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)
    }
}



Now, a closure tries to invoke the `foo` method via a context delegate, as
shown below:

def closure = { it -> foo() }
closure.delegate = new Context([:])
closure.setResolveStrategy(Closure.DELEGATE_ONLY)
assert closure.call() == 'OK'



However, the above snipper fails with the following message:

java.lang.Exception: Missing key: foo


Why does the closure try to access the `foo` attribute instead of invoking
it as a method? This code works as expected with Groovy 3.



Thanks,
Paolo

Reply via email to