Control variables in for loops are read only

This commit is contained in:
Roberto Ierusalimschy
2022-12-21 12:04:59 -03:00
parent 540d805226
commit b2f7b3b79f
5 changed files with 40 additions and 37 deletions

View File

@@ -236,7 +236,7 @@ package.path = oldpath
local fname = "file_does_not_exist2"
local m, err = pcall(require, fname)
for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do
t = string.gsub(t, "?", fname)
local t = string.gsub(t, "?", fname)
assert(string.find(err, t, 1, true))
end

View File

@@ -60,32 +60,29 @@ end
-- testing closures with 'for' control variable
a = {}
for i=1,10 do
a[i] = {set = function(x) i=x end, get = function () return i end}
a[i] = function () return i end
if i == 3 then break end
end
assert(a[4] == undef)
a[1].set(10)
assert(a[2].get() == 2)
a[2].set('a')
assert(a[3].get() == 3)
assert(a[2].get() == 'a')
assert(a[2]() == 2)
assert(a[3]() == 3)
a = {}
local t = {"a", "b"}
for i = 1, #t do
local k = t[i]
a[i] = {set = function(x, y) i=x; k=y end,
a[i] = {set = function(x) k=x end,
get = function () return i, k end}
if i == 2 then break end
end
a[1].set(10, 20)
a[1].set(10)
local r,s = a[2].get()
assert(r == 2 and s == 'b')
r,s = a[1].get()
assert(r == 10 and s == 20)
a[2].set('a', 'b')
assert(r == 1 and s == 10)
a[2].set('a')
r,s = a[2].get()
assert(r == "a" and s == "b")
assert(r == 2 and s == "a")
-- testing closures with 'for' control variable x break

View File

@@ -609,10 +609,12 @@ do
a = 0; for i=1.0, 0.99999, -1 do a=a+1 end; assert(a==1)
end
do -- changing the control variable
local a
a = 0; for i = 1, 10 do a = a + 1; i = "x" end; assert(a == 10)
a = 0; for i = 10.0, 1, -1 do a = a + 1; i = "x" end; assert(a == 10)
do -- attempt to change the control variable
local st, msg = load "for i = 1, 10 do i = 10 end"
assert(not st and string.find(msg, "assign to const variable 'i'"))
local st, msg = load "for v, k in pairs{} do v = 10 end"
assert(not st and string.find(msg, "assign to const variable 'v'"))
end
-- conversion