diff options
| author | Roberto I <roberto@inf.puc-rio.br> | 2025-11-11 15:11:06 -0300 |
|---|---|---|
| committer | Roberto I <roberto@inf.puc-rio.br> | 2025-11-11 15:11:06 -0300 |
| commit | 4cf498210e6a60637a7abb06d32460ec21efdbdc (patch) | |
| tree | 7b9cffee61083a6b256311917019b58a1fbdd42a | |
| parent | 5b7d9987642f72d44223a8e5e79e013bb2b3d579 (diff) | |
| download | lua-master.tar.gz lua-master.tar.bz2 lua-master.zip | |
| -rw-r--r-- | lbaselib.c | 13 | ||||
| -rw-r--r-- | manual/manual.of | 4 | ||||
| -rw-r--r-- | testes/nextvar.lua | 7 |
3 files changed, 15 insertions, 9 deletions
| @@ -279,21 +279,22 @@ static int luaB_next (lua_State *L) { | |||
| 279 | 279 | ||
| 280 | static int pairscont (lua_State *L, int status, lua_KContext k) { | 280 | static int pairscont (lua_State *L, int status, lua_KContext k) { |
| 281 | (void)L; (void)status; (void)k; /* unused */ | 281 | (void)L; (void)status; (void)k; /* unused */ |
| 282 | return 3; | 282 | return 4; /* __pairs did all the work, just return its results */ |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | static int luaB_pairs (lua_State *L) { | 285 | static int luaB_pairs (lua_State *L) { |
| 286 | luaL_checkany(L, 1); | 286 | luaL_checkany(L, 1); |
| 287 | if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */ | 287 | if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */ |
| 288 | lua_pushcfunction(L, luaB_next); /* will return generator, */ | 288 | lua_pushcfunction(L, luaB_next); /* will return generator and */ |
| 289 | lua_pushvalue(L, 1); /* state, */ | 289 | lua_pushvalue(L, 1); /* state */ |
| 290 | lua_pushnil(L); /* and initial value */ | 290 | lua_pushnil(L); /* initial value */ |
| 291 | lua_pushnil(L); /* to-be-closed object */ | ||
| 291 | } | 292 | } |
| 292 | else { | 293 | else { |
| 293 | lua_pushvalue(L, 1); /* argument 'self' to metamethod */ | 294 | lua_pushvalue(L, 1); /* argument 'self' to metamethod */ |
| 294 | lua_callk(L, 1, 3, 0, pairscont); /* get 3 values from metamethod */ | 295 | lua_callk(L, 1, 4, 0, pairscont); /* get 4 values from metamethod */ |
| 295 | } | 296 | } |
| 296 | return 3; | 297 | return 4; |
| 297 | } | 298 | } |
| 298 | 299 | ||
| 299 | 300 | ||
diff --git a/manual/manual.of b/manual/manual.of index eaf0ce78..9b6976ca 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
| @@ -6799,11 +6799,11 @@ In particular, you may set existing fields to nil. | |||
| 6799 | @LibEntry{pairs (t)| | 6799 | @LibEntry{pairs (t)| |
| 6800 | 6800 | ||
| 6801 | If @id{t} has a metamethod @idx{__pairs}, | 6801 | If @id{t} has a metamethod @idx{__pairs}, |
| 6802 | calls it with @id{t} as argument and returns the first three | 6802 | calls it with @id{t} as argument and returns the first four |
| 6803 | results from the call. | 6803 | results from the call. |
| 6804 | 6804 | ||
| 6805 | Otherwise, | 6805 | Otherwise, |
| 6806 | returns three values: the @Lid{next} function, the table @id{t}, and @nil, | 6806 | returns the @Lid{next} function, the table @id{t}, plus two @nil values, |
| 6807 | so that the construction | 6807 | so that the construction |
| 6808 | @verbatim{ | 6808 | @verbatim{ |
| 6809 | for k,v in pairs(t) do @rep{body} end | 6809 | for k,v in pairs(t) do @rep{body} end |
diff --git a/testes/nextvar.lua b/testes/nextvar.lua index 7e5bed56..098e7891 100644 --- a/testes/nextvar.lua +++ b/testes/nextvar.lua | |||
| @@ -905,13 +905,18 @@ local function foo1 (e,i) | |||
| 905 | if i <= e.n then return i,a[i] end | 905 | if i <= e.n then return i,a[i] end |
| 906 | end | 906 | end |
| 907 | 907 | ||
| 908 | setmetatable(a, {__pairs = function (x) return foo, x, 0 end}) | 908 | local closed = false |
| 909 | setmetatable(a, {__pairs = function (x) | ||
| 910 | local tbc = setmetatable({}, {__close = function () closed = true end}) | ||
| 911 | return foo, x, 0, tbc | ||
| 912 | end}) | ||
| 909 | 913 | ||
| 910 | local i = 0 | 914 | local i = 0 |
| 911 | for k,v in pairs(a) do | 915 | for k,v in pairs(a) do |
| 912 | i = i + 1 | 916 | i = i + 1 |
| 913 | assert(k == i and v == k+1) | 917 | assert(k == i and v == k+1) |
| 914 | end | 918 | end |
| 919 | assert(closed) -- 'tbc' has been closed | ||
| 915 | 920 | ||
| 916 | a.n = 5 | 921 | a.n = 5 |
| 917 | a[3] = 30 | 922 | a[3] = 30 |
