Groovy, кажется, имеет очень неприятное поведение, связанное с "Groovy Beans" и замыканиями, которые могут заставить его маскировать локальные переменные в определенных обстоятельствах.
Известно ли это поведение и есть ли где-нибудь документация, подробно описывающая это? Я потратил много времени, пытаясь понять, что не работает...
Рассмотрим следующий код:
class TestClass {
def doIt(Closure closure) {
closure.setDelegate(this)
closure.call()
}
def getRevision() {
return "testclass revision"
}
}
def testIt() {
def revision = "testit revision"
println "1: " + revision + " (expect: testit)"
TestClass tester = new TestClass()
tester.doIt {
println "2: " + getRevision() + " (expect: testclass)"
}
println "3: " + revision + " (expect: testit)"
tester.doIt {
println "4: " + revision + " (expect: testit)"
revision = getRevision()
println "5: " + revision + " (expect: testclass)"
println "6: ${getRevision()} (expect: testclass)"
println "7: " + getRevision() + " (expect: testclass)"
}
// expect to have been set to testclass value in previous closure
println "8: " + revision + " (expect: testclass)"
tester.doIt {
println "9: ${getRevision()} (expect: testclass)"
println "10: " + getRevision() + " (expect: testclass)"
}
println "11: " + revision + " (expect: testclass)"
}
testIt()
Выполнение этого кода приводит к следующему выводу:
1: testit revision (expect: testit)
2: testclass revision (expect: testclass)
3: testit revision (expect: testit)
4: testit revision (expect: testit)
5: testit revision (expect: testclass)
6: testit revision (expect: testclass)
7: testit revision (expect: testclass)
8: testit revision (expect: testclass)
9: testclass revision (expect: testclass)
10: testclass revision (expect: testclass)
11: testit revision (expect: testclass)
Моя основная проблема связана с 5/6/7. Кажется, что простое использование локальной переменной revision
внутри замыкания «скрывает» метод getRevision()
в делегате и заменяет его автоматически -сгенерированным getRevision()
в стиле bean-компонента -в соответствии с revision
" имущество". Если я не использую переменную revision
, вызовы getRevision()
не вызывают это поведение компонента.
Будем признательны за любую информацию или ссылки на документацию!