Нашел похожий вопрос почти пятилетней давности: Различное разрешение вложенного замыкания между методами и свойствами? Видимо, это ошибка, и с тех пор она была открыта без каких-либо изменений: https://issues.apache.org/jira/browse/GROOVY-7232
Связанный пост отмечает кое-что, что я также заметил: свойства правильно разрешены делегату, но не вызовы методов. Вот переработанный пример, демонстрирующий это:
class Clazz {
String name
void doit(Clazz clazz) {
def cl = {
println "Outer closure: property=${name}, method=${getName()}"
{->
println "Inner closure: property=${name}, method=${getName()}"
}.call()
}
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl.delegate = clazz
cl()
}
}
def a = new Clazz(name: 'A')
def b = new Clazz(name: 'B')
a.doit(b)
Результат:
Outer closure: property=B, method=B
Inner closure: property=B, method=A
Кто-то в связанном посте опубликовал обходной путь, используя регидрат . В моем случае это работает (вроде) только в том случае, если заменены все ссылки, включая this !
class Clazz {
String name
void doit(Clazz clazz) {
def cl = {
println "Outer closure: property=${name}, method=${getName()}"
{->
println "Inner closure: property=${name}, method=${getName()}"
}.call()
}
cl.rehydrate(clazz, clazz, clazz)()
}
}
def a = new Clazz(name: 'A')
def b = new Clazz(name: 'B')
a.doit(b)
Результат:
Outer closure: property=B, method=B
Inner closure: property=B, method=B