Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
None
Description
Closure using a variable outside its enclosing block has inconsistant behavior. A series of tests demonstrate the issue. In most cases if the closure is defined in a function/method works fine, but behaves incorrectly in script code (in the invisible main ). The test to demonstrate the problem is as follows:
println "Tests for groovy closure's use of 'outer scope variable'"
println "Sone strange behavior"
println "Some are a little unexpected but correct - but fails the 'least unexpected' test"
def test0() {
def list = []
for(i in ["red","green","blue"]) {
list <<
{ println i }}
i = "Strange"
println println "Test0 logical – although somewhat unexpected - prints Strange ... \n-------"
// execute each of the 3 closures in 'list'
for( x in list) { x() }
println()
}
def test1() {
def list = []
for(i in ["red","green","blue"]) {
def v = i
list << { println v }
}
println "Test1 Fix test0 to give the desired behavior\n-------"
// execute each of the 3 closures in 'list'
for( x in list) { x() }
println()
}
// An alternative method of achieving the expected behavior
def test2() {
def list = []
for(i in ["red","green","blue"]) {
list << { println it }.curry
}
println "Test2 OK (another way to fix the problem using curry)\n-------"
// execute each of the 3 closures in 'list'
for( x in list) { x() }
println()
}
//
def test3() {
def lis = []
["red","green","blue"].each { v ->
lis << { println v }
}
println "Test3 OK\n-------"
for( x in lis ) { x() }
println()
}
//
def test3A() {
def lis = []
["red","green","blue"].each { v ->
def X = v
lis << { println X }
}
println "Test3A OK – very similar to test3\n-------"
for( x in lis ) { x() }
println()
}
// Execute the tests
test0()
test1()
test2()
test3()
test3A()
// This is code outside of a function
// this does not work right
// Test4
def list = []
for(i in ["red","green","blue"]) {
def v = i
list << { println v }
}
println "Test4, Should have given red blue green \n-------"
for( x in list) { x() }
println()
// Test 5
def lis = []
["red","green","blue"].each { i ->
lis << { println i }
}
println "Test5, does give red blue green \n-------"
for( x in lis)
println()
// Test 5A
def lisx = []
["red","green","blue"].each { v ->
def X = v
lisx << { println X }
}
println "Test5A, is almost identical to test3A, but behaves differently \n-------"
for( x in lisx) { x() }
println()
// Test 6
def li = []
println "Test6, fails again \n-------"
["red","green","blue"].each { s ->
def v1 = s
li <<
}
for( x in li)
{ x() }
println()
Attachments
Attachments
Issue Links
- is depended upon by
-
GROOVY-754 scoping
- Closed