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 <[email protected]>
Sent: Thursday, September 4, 2025 5:54 PM
To: Groovy_Developers <[email protected]>
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>