lua-users home
lua-l archive

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


On Tue, Jan 26, 2010 at 6:42 PM, Patrick Donnelly wrote:
> I would agree that using an 'n' field is an odd about-face for Lua
> after the changes in 5.0 -> 5.1. It would be easier to just return a
> second value and allow the programmer to set his own convention.

Consider something like this patch to table.unpack:


-- test suite for patch
local function g(n) return table.unpack({0}, 1, n) end
local function f(n)
  local results = {g(n)}   -- note: nil's are preserved via Table
sizearray field
  if results[1] then results[1] = true end -- edits allowed if does
not resize table
  return table.unpack(results)  -- uses sizearray, not length, by default
end
for n=1,2000 do assert(select('#', f(n)) == n, n) end
print 'OK'


diff -ur lua-5.2.0-work2/src/lapi.c lua-5.2.0-work2-patch/src/lapi.c
--- lua-5.2.0-work2/src/lapi.c
+++ lua-5.2.0-work2-patch/src/lapi.c
@@ -385,6 +385,15 @@
 }


+LUA_API size_t lua_asize (lua_State *L, int idx) {
+  StkId o = index2addr(L, idx);
+  switch (ttype(o)) {
+    case LUA_TTABLE: return hvalue(o)->sizearray;
+    default: return 0;
+  }
+}
+
+
 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
   StkId o = index2addr(L, idx);
   return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
diff -ur lua-5.2.0-work2/src/ltable.c lua-5.2.0-work2-patch/src/ltable.c
--- lua-5.2.0-work2/src/ltable.c
+++ lua-5.2.0-work2-patch/src/ltable.c
@@ -32,7 +32,7 @@
 #include "lobject.h"
 #include "lstate.h"
 #include "ltable.h"
-
+#include <stdio.h> /*DEBUG*/

 /*
 ** max size of array part is 2^MAXBITS
@@ -266,6 +266,7 @@
   luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
   for (i=t->sizearray; i<size; i++)
      setnilvalue(&t->array[i]);
+  printf("DEBUG:[setarrayvector:%d->%d]\n", t->sizearray, size);
   t->sizearray = size;
 }

@@ -306,6 +307,7 @@
   setnodevector(L, t, nhsize);
   if (nasize < oldasize) {  /* array part must shrink? */
     t->sizearray = nasize;
+    printf("DEBUG:[luaH_resize:%d]\n", nasize);
     /* re-insert elements from vanishing slice */
     for (i=nasize; i<oldasize; i++) {
       if (!ttisnil(&t->array[i]))
diff -ur lua-5.2.0-work2/src/ltablib.c lua-5.2.0-work2-patch/src/ltablib.c
--- lua-5.2.0-work2/src/ltablib.c	2010-01-13 14:59:10.000000000 -0500
+++ lua-5.2.0-work2-patch/src/ltablib.c	2010-01-26 21:27:29.875000000 -0500
@@ -188,7 +188,7 @@
   int i, e, n;
   luaL_checktype(L, 1, LUA_TTABLE);
   i = luaL_optint(L, 2, 1);
-  e = luaL_opt(L, luaL_checkint, 3, (int)lua_rawlen(L, 1));
+  e = luaL_opt(L, luaL_checkint, 3, (int)lua_asize(L, 1));
   if (i > e) return 0;  /* empty range */
   n = e - i + 1;  /* number of elements */
   if (n <= 0 || !lua_checkstack(L, n))  /* n <= 0 means arith. overflow */
diff -ur lua-5.2.0-work2/src/lua.h lua-5.2.0-work2-patch/src/lua.h
--- lua-5.2.0-work2/src/lua.h	2010-01-13 20:40:04.000000000 -0500
+++ lua-5.2.0-work2-patch/src/lua.h	2010-01-26 22:06:51.578125000 -0500
@@ -157,6 +157,7 @@
 LUA_API int             (lua_toboolean) (lua_State *L, int idx);
 LUA_API const char     *(lua_tolstring) (lua_State *L, int idx, size_t *len);
 LUA_API size_t          (lua_rawlen) (lua_State *L, int idx);
+LUA_API size_t          (lua_asize) (lua_State *L, int idx);
 LUA_API lua_CFunction   (lua_tocfunction) (lua_State *L, int idx);
 LUA_API void	       *(lua_touserdata) (lua_State *L, int idx);
 LUA_API lua_State      *(lua_tothread) (lua_State *L, int idx);