diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-02-28 10:10:27 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-02-28 10:10:27 -0300 |
commit | 127a8e80fe0d74efd26994b3877cdc77b712ea56 (patch) | |
tree | 12b8b3be0660884f4a1075af37e0f58cbd43a3d3 /testes | |
parent | f9e35627ed26dff4114a1d01ff113d8b4cc91ab5 (diff) | |
download | lua-127a8e80fe0d74efd26994b3877cdc77b712ea56.tar.gz lua-127a8e80fe0d74efd26994b3877cdc77b712ea56.tar.bz2 lua-127a8e80fe0d74efd26994b3877cdc77b712ea56.zip |
'__close' gets no error object if there is no error
Instead of receiving nil as a second argument, __close metamethods are
called with just one argument when there are no errors.
Diffstat (limited to 'testes')
-rw-r--r-- | testes/locals.lua | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/testes/locals.lua b/testes/locals.lua index 090d846b..910deb8a 100644 --- a/testes/locals.lua +++ b/testes/locals.lua | |||
@@ -280,6 +280,32 @@ do | |||
280 | end | 280 | end |
281 | 281 | ||
282 | 282 | ||
283 | do -- testing presence of second argument | ||
284 | local function foo (howtoclose, obj, n) | ||
285 | local ca -- copy of 'a' visible inside its close metamethod | ||
286 | do | ||
287 | local a <close> = func2close(function (...) | ||
288 | local t = table.pack(...) | ||
289 | assert(select("#", ...) == n) | ||
290 | assert(t.n == n and t[1] == ca and (t.n < 2 or t[2] == obj)) | ||
291 | ca = 15 -- final value to be returned if howtoclose=="scope" | ||
292 | end) | ||
293 | ca = a | ||
294 | if howtoclose == "ret" then return obj -- 'a' closed by return | ||
295 | elseif howtoclose == "err" then error(obj) -- 'a' closed by error | ||
296 | end | ||
297 | end -- 'a' closed by end of scope | ||
298 | return ca -- ca now should be 15 | ||
299 | end | ||
300 | -- with no errors, closing methods receive no extra argument | ||
301 | assert(foo("scope", nil, 1) == 15) -- close by end of scope | ||
302 | assert(foo("ret", 32, 1) == 32) -- close by return | ||
303 | -- with errors, they do | ||
304 | local st, msg = pcall(foo, "err", 23, 2) -- close by error | ||
305 | assert(not st and msg == 23) | ||
306 | end | ||
307 | |||
308 | |||
283 | -- testing to-be-closed x compile-time constants | 309 | -- testing to-be-closed x compile-time constants |
284 | -- (there were some bugs here in Lua 5.4-rc3, due to a confusion | 310 | -- (there were some bugs here in Lua 5.4-rc3, due to a confusion |
285 | -- between compile levels and stack levels of variables) | 311 | -- between compile levels and stack levels of variables) |
@@ -865,8 +891,10 @@ do | |||
865 | if extra then | 891 | if extra then |
866 | extrares = co() -- runs until first (extra) yield | 892 | extrares = co() -- runs until first (extra) yield |
867 | end | 893 | end |
868 | local res = table.pack(co()) -- runs until yield inside '__close' | 894 | local res = table.pack(co()) -- runs until "regular" yield |
869 | assert(res.n == 2 and res[2] == nil) | 895 | -- regular yield will yield all values passed to the close function; |
896 | -- without errors, that is only the object being closed. | ||
897 | assert(res.n == 1 and type(res[1]) == "table") | ||
870 | local res2 = table.pack(co()) -- runs until end of function | 898 | local res2 = table.pack(co()) -- runs until end of function |
871 | assert(res2.n == t.n) | 899 | assert(res2.n == t.n) |
872 | for i = 1, #t do | 900 | for i = 1, #t do |
@@ -879,10 +907,10 @@ do | |||
879 | end | 907 | end |
880 | 908 | ||
881 | local function foo () | 909 | local function foo () |
882 | local x <close> = func2close(coroutine.yield) | 910 | local x <close> = func2close(coroutine.yield) -- "regular" yield |
883 | local extra <close> = func2close(function (self) | 911 | local extra <close> = func2close(function (self) |
884 | assert(self == extrares) | 912 | assert(self == extrares) |
885 | coroutine.yield(100) | 913 | coroutine.yield(100) -- first (extra) yield |
886 | end) | 914 | end) |
887 | extrares = extra | 915 | extrares = extra |
888 | return table.unpack{10, x, 30} | 916 | return table.unpack{10, x, 30} |
@@ -891,21 +919,21 @@ do | |||
891 | assert(extrares == 100) | 919 | assert(extrares == 100) |
892 | 920 | ||
893 | local function foo () | 921 | local function foo () |
894 | local x <close> = func2close(coroutine.yield) | 922 | local x <close> = func2close(coroutine.yield) -- "regular" yield |
895 | return | 923 | return |
896 | end | 924 | end |
897 | check(foo, false) | 925 | check(foo, false) |
898 | 926 | ||
899 | local function foo () | 927 | local function foo () |
900 | local x <close> = func2close(coroutine.yield) | 928 | local x <close> = func2close(coroutine.yield) -- "regular" yield |
901 | local y, z = 20, 30 | 929 | local y, z = 20, 30 |
902 | return x | 930 | return x |
903 | end | 931 | end |
904 | check(foo, false, "x") | 932 | check(foo, false, "x") |
905 | 933 | ||
906 | local function foo () | 934 | local function foo () |
907 | local x <close> = func2close(coroutine.yield) | 935 | local x <close> = func2close(coroutine.yield) -- "regular" yield |
908 | local extra <close> = func2close(coroutine.yield) | 936 | local extra <close> = func2close(coroutine.yield) -- extra yield |
909 | return table.unpack({}, 1, 100) -- 100 nils | 937 | return table.unpack({}, 1, 100) -- 100 nils |
910 | end | 938 | end |
911 | check(foo, true, table.unpack({}, 1, 100)) | 939 | check(foo, true, table.unpack({}, 1, 100)) |