diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-10-31 14:54:45 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-10-31 14:54:45 -0300 |
commit | 947a372f5860a76fcafb4a2845abc322e440d6fc (patch) | |
tree | e35840847207c850af5262f93f863f583d2af76d /testes | |
parent | e073cbc2e538369e0611abfc9948f301aea6aef3 (diff) | |
download | lua-947a372f5860a76fcafb4a2845abc322e440d6fc.tar.gz lua-947a372f5860a76fcafb4a2845abc322e440d6fc.tar.bz2 lua-947a372f5860a76fcafb4a2845abc322e440d6fc.zip |
State in generic 'for' acts as a to-be-closed variable
The implicit variable 'state' in a generic 'for' is marked as a
to-be-closed variable, so that the state will be closed as soon
as the loop ends, no matter how.
Taking advantage of this new facility, the call 'io.lines(filename)'
now returns the open file as a second result. Therefore,
an iteraction like 'for l in io.lines(name)...' will close the
file even when the loop ends with a break or an error.
Diffstat (limited to 'testes')
-rw-r--r-- | testes/files.lua | 8 | ||||
-rw-r--r-- | testes/locals.lua | 50 |
2 files changed, 53 insertions, 5 deletions
diff --git a/testes/files.lua b/testes/files.lua index 9aae5913..a11c5e61 100644 --- a/testes/files.lua +++ b/testes/files.lua | |||
@@ -462,13 +462,13 @@ X | |||
462 | - y; | 462 | - y; |
463 | ]]:close() | 463 | ]]:close() |
464 | _G.X = 1 | 464 | _G.X = 1 |
465 | assert(not load(io.lines(file))) | 465 | assert(not load((io.lines(file)))) |
466 | collectgarbage() -- to close file in previous iteration | 466 | collectgarbage() -- to close file in previous iteration |
467 | load(io.lines(file, "L"))() | 467 | load((io.lines(file, "L")))() |
468 | assert(_G.X == 2) | 468 | assert(_G.X == 2) |
469 | load(io.lines(file, 1))() | 469 | load((io.lines(file, 1)))() |
470 | assert(_G.X == 4) | 470 | assert(_G.X == 4) |
471 | load(io.lines(file, 3))() | 471 | load((io.lines(file, 3)))() |
472 | assert(_G.X == 8) | 472 | assert(_G.X == 8) |
473 | 473 | ||
474 | print('+') | 474 | print('+') |
diff --git a/testes/locals.lua b/testes/locals.lua index 65b145db..1e0f525b 100644 --- a/testes/locals.lua +++ b/testes/locals.lua | |||
@@ -108,7 +108,7 @@ print'+' | |||
108 | if rawget(_G, "T") then | 108 | if rawget(_G, "T") then |
109 | -- testing clearing of dead elements from tables | 109 | -- testing clearing of dead elements from tables |
110 | collectgarbage("stop") -- stop GC | 110 | collectgarbage("stop") -- stop GC |
111 | local a = {[{}] = 4, [3] = 0, alo = 1, | 111 | local a = {[{}] = 4, [3] = 0, alo = 1, |
112 | a1234567890123456789012345678901234567890 = 10} | 112 | a1234567890123456789012345678901234567890 = 10} |
113 | 113 | ||
114 | local t = T.querytab(a) | 114 | local t = T.querytab(a) |
@@ -360,6 +360,54 @@ end) | |||
360 | co() -- start coroutine | 360 | co() -- start coroutine |
361 | assert(co == nil) -- eventually it will be collected | 361 | assert(co == nil) -- eventually it will be collected |
362 | 362 | ||
363 | |||
364 | -- to-be-closed variables in generic for loops | ||
365 | do | ||
366 | local numopen = 0 | ||
367 | local function open (x) | ||
368 | numopen = numopen + 1 | ||
369 | return | ||
370 | function () -- iteraction function | ||
371 | x = x - 1 | ||
372 | if x > 0 then return x end | ||
373 | end, | ||
374 | function () -- closing function | ||
375 | numopen = numopen - 1 | ||
376 | end | ||
377 | end | ||
378 | |||
379 | local s = 0 | ||
380 | for i in open(10) do | ||
381 | s = s + i | ||
382 | end | ||
383 | assert(s == 45 and numopen == 0) | ||
384 | |||
385 | local s = 0 | ||
386 | for i in open(10) do | ||
387 | if i < 5 then break end | ||
388 | s = s + i | ||
389 | end | ||
390 | assert(s == 35 and numopen == 0) | ||
391 | |||
392 | -- repeat test with '__open' metamethod instead of a function | ||
393 | local function open (x) | ||
394 | numopen = numopen + 1 | ||
395 | return | ||
396 | function (t) -- iteraction function | ||
397 | t[1] = t[1] - 1 | ||
398 | if t[1] > 0 then return t[1] end | ||
399 | end, | ||
400 | setmetatable({x}, {__close = function () numopen = numopen - 1 end}) | ||
401 | end | ||
402 | |||
403 | local s = 0 | ||
404 | for i in open(10) do | ||
405 | if (i < 5) then break end | ||
406 | s = s + i | ||
407 | end | ||
408 | assert(s == 35 and numopen == 0) | ||
409 | end | ||
410 | |||
363 | print('OK') | 411 | print('OK') |
364 | 412 | ||
365 | return 5,f | 413 | return 5,f |