for-each and for-in always declare a new collection variable, which may have its type elided. And now an index variable is also supported.
def foo = null for (foo : []) {} for (foo in []) {} should produce an error of duplicate variable declared in outer scope. for (classic) is a sequence of three expressions. I don't think there is a hard requirement of a variable declaration expression as the first expression. So "foo = 1" is seen as an assignment not a declaration. There may be some history where the variables were all set into script binding ________________________________ From: Ondra Cada <o...@ocs.cz> Sent: Thursday, September 4, 2025 5:54 PM To: Groovy_Developers <dev@groovy.apache.org> Subject: [EXT] Ugly inconsistence betw. for and for/in External Email: Use caution with links and attachments. Hi there, I've just bumped into the problem that the c-like for properly scopes/does not scope based on whether its control variable is declared or just used, whilst for/in always scopes, regardless the form (see the example below for detailed explanation). Is this a bug or an intended behaviour? It would be nice to fix it so that for/in does not scope when there's no declaration, but I fear it might be a breaking change for legacy code :( Thanks and all the best, OC === 5 ocs /tmp> <q.groovy class Foo { def foo def bar() { println "foo='$foo'" } def test() { println "Should not change" for (def foo in [1,2]) bar() println "Precisely like does not here" for (def foo=1; foo<3; foo++) bar() println "Should change but does not" for (foo in [1,2]) bar() println "Precisely like does here" for (foo=1; foo<3; foo++) bar() } static main(args) { Foo.newInstance().test() } } 6 ocs /tmp> groovy q Should not change foo='null' foo='null' Precisely like does not here foo='null' foo='null' Should change but does not foo='null' foo='null' Precisely like does here foo='1' foo='2' 7 ocs /tmp> groovy -version Groovy Version: 4.0.27 JVM: 1.8.0_452 Vendor: Tencent OS: Mac OS X 8 ocs /tmp>