lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 2017-01-24 14:11, Luiz Henrique de Figueiredo wrote:
> Exactly. Now is the time to report glitches.

I actually found one just now.

This (lbaselib.c):

@@ -208,8 +208,8 @@
 static int pairsmeta (lua_State *L, const char *method, int iszero,
                       lua_CFunction iter) {
+  luaL_checkany(L, 1);
   if (luaL_getmetafield(L, 1, method) == LUA_TNIL) {  /* no metamethod? */
-    luaL_checktype(L, 1, LUA_TTABLE);  /* argument must be a table */
     lua_pushcfunction(L, iter);  /* will return generator, */
     lua_pushvalue(L, 1);  /* state, */
     if (iszero) lua_pushinteger(L, 0);  /* and initial value */

leads to:

5.3.3> pairs( 1 )
stdin:1: bad argument #1 to 'pairs' (table expected, got number)
5.3.4> pairs( 1 )
next, 1, nil

This breaks when using

    local has_pairs = pcall( pairs, v )

as a short-cut for checking if it's a table or has __pairs.  (You may
not be able to access the metatable in restricted environments without
debug.getmetatable if __metatable hides it.)

The test can be adjusted to

    local has_pairs = pcall( select( 2, pcall( pairs, v ) ) )

or simply

    local has_pairs = pcall( pairs( v ) )

if you don't care about the past, but the old behavior was stable since
(at least) 5.1, so it may not be something to break in a minor release.

(I have a mild preference for the old behavior (throw "type" errors as
early as possible) but don't really care either way.)

-- nobody