lua-users home
lua-l archive

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


Now I realize that this is probably overly pedantic, but I'd like to see
what others think...

The lua 5.1 reference manual claims that pairs(t)

"Returns three values: the 'next' function, the table t, and nil".
(where 'next' is a link to the function named 'next').

This is not strictly so, as can easily be seen:

next -> function: 00324328
pairs{} -> function: 00324FD8      table: 0032F7A8 nil

The first return value of pairs(t) is rather a private function that
invokes that same code (luaB_next) that 'next' invokes.  But it does
_not_ return 'next' per se.

So either the documentation should be fixed, or the following patch
could be applied which makes the reference manual true.  This patch
both the advantage and the disadvantage that if the value of 'next'
is changed, then pairs(t) will see that change.

Index: lbaselib.c
===================================================================
--- lbaselib.c	(revision 3)
+++ lbaselib.c	(revision 4)
@@ -237,7 +237,7 @@
 
 static int luaB_pairs (lua_State *L) {
   luaL_checktype(L, 1, LUA_TTABLE);
-  lua_pushvalue(L, lua_upvalueindex(1));  /* return generator, */
+  lua_getglobal(L, "next");	/* return generator */
   lua_pushvalue(L, 1);  /* state, */
   lua_pushnil(L);  /* and initial value */
   return 3;
@@ -454,6 +454,7 @@
   {"load", luaB_load},
   {"loadstring", luaB_loadstring},
   {"next", luaB_next},
+  {"pairs", luaB_pairs},
   {"pcall", luaB_pcall},
   {"print", luaB_print},
   {"rawequal", luaB_rawequal},
@@ -605,14 +606,6 @@
 /* }====================================================== */
 
 
-static void auxopen (lua_State *L, const char *name,
-                     lua_CFunction f, lua_CFunction u) {
-  lua_pushcfunction(L, u);
-  lua_pushcclosure(L, f, 1);
-  lua_setfield(L, -2, name);
-}
-
-
 static void base_open (lua_State *L) {
   /* set global _G */
   lua_pushvalue(L, LUA_GLOBALSINDEX);
@@ -621,9 +614,10 @@
   luaL_register(L, "_G", base_funcs);
   lua_pushliteral(L, LUA_VERSION);
   lua_setglobal(L, "_VERSION");  /* set global _VERSION */
-  /* `ipairs' and `pairs' need auxliliary functions as upvalues */
-  auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
-  auxopen(L, "pairs", luaB_pairs, luaB_next);
+  /* `ipairs' need an auxliliary function as an upvalue */
+  lua_pushcfunction(L, ipairsaux);
+  lua_pushcclosure(L, luaB_ipairs, 1);
+  lua_setfield(L, -2, "ipairs");	/* _G[ "ipairs" ] = closure */
   /* `newproxy' needs a weaktable as upvalue */
   lua_createtable(L, 0, 1);  /* new table `w' */
   lua_pushvalue(L, -1);  /* `w' will be its own metatable */

I donate this code to whoever wants it, for whatever reason,
to relicense it in whatever way they want.

- Eric