diff --git a/lib/nodes.js b/lib/nodes.js index c1de8a24..7e053a12 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1542,7 +1542,7 @@ }); name = !this.pattern && ((_ref = this.name) != null ? _ref.compile(o) : void 0); index = (_ref2 = this.index) != null ? _ref2.compile(o) : void 0; - ivar = !index || hasCode ? scope.freeVariable('i') : index; + ivar = !index ? scope.freeVariable('i') : index; varPart = guardPart = defPart = retPart = ''; idt = this.idt(1); if (!hasCode) { diff --git a/src/nodes.coffee b/src/nodes.coffee index bfb915b0..7f68b57d 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1293,7 +1293,7 @@ exports.For = class For extends Base hasCode = @body.contains (node) -> node instanceof Code name = not @pattern and @name?.compile o index = @index?.compile o - ivar = if not index or hasCode then scope.freeVariable 'i' else index + ivar = if not index then scope.freeVariable 'i' else index varPart = guardPart = defPart = retPart = '' idt = @idt 1 unless hasCode diff --git a/test/test_comprehensions.coffee b/test/test_comprehensions.coffee index 981c4169..f1c016f3 100644 --- a/test/test_comprehensions.coffee +++ b/test/test_comprehensions.coffee @@ -46,6 +46,43 @@ ok 2 of evens all = from = to = 1 +# Ensure that the closure wrapper preserves local variables. +obj = {} + +for method in ['one', 'two', 'three'] + obj[method] = -> + "I'm " + method + +ok obj.one() is "I'm one" +ok obj.two() is "I'm two" +ok obj.three() is "I'm three" + +i = 0 +for i from 1 to 3 + -> 'func' + break if false +ok i is 4 + + +# Ensure that local variables are closed over for range comprehensions. +funcs = for i from 1 to 3 + -> -i + +ok (func() for func in funcs).join(' ') is '-1 -2 -3' +ok i is 4 + + +# Even when referenced in the filter. +list = ['one', 'two', 'three'] + +methods = for num, i in list when num isnt 'two' and i isnt 1 + -> num + ' ' + i + +ok methods.length is 2 +ok methods[0]() is 'one 0' +ok methods[1]() is 'three 2' + + # Nested comprehensions. multiLiner = for x from 3 to 5