lua-users home
lua-l archive

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


This is a "feature" of lua which has become more opaque in Lua 5.  The
workaround is:

  If you need to set numerical table entries directly, always use
  table.setn afterwards (if you expect to use any table functions).

To get a better idea of what is happening, look at Lua 4:

Lua 4.0.1  Copyright (C) 1994-2000 TeCGraf, PUC-Rio
> t={'a','b','c'}
> tremove(t,3)		-- implicitly does "setn"
> foreach(t,print)
1       a
2       b
n       2
> t[3]='c'
> foreach(t,print)
1       a
2       b
3       c
n       2
> tremove(t,3)		-- uses equivalent of "getn" to determine end
> foreach(t,print)
1       a
3       c
n       1

Lua 5 does essentially the same thing, but you don't see the "n".  While
I am in favor of not having a special "n" in the table, I believe that
this behavior is bad.  It has actually become worse in Lua 5.  Now, any
function which does an implicit getn also does a setn (like
table.foreachi).  For example:

Lua 5.0 (beta)  Copyright (C) 1994-2002 Tecgraf, PUC-Rio
> t={'a','b'}
> table.foreachi(t,print)	-- implicit setn
1       a
2       b
> t[3]='c'
> table.foreachi(t,print)
1       a
2       b

You will have the same problem if you iterate using for:

for i = 1, getn(t) do
  print(t[i])
end

Of course this change was documented, but I don't really like it.  It
seems like an optimization, but when you are using table.insert to build
your table the hidden "n" is already set, so you save nothing.  If you
inserted entries directly, you may be surprised by the behavior.

My preference would be that doing a direct table assignment also updates
the internal "n" value.  Of course, that would slow Lua down, which is
an issue for many.  I wanted to look into this further and maybe come up
with a patch, but I am currently far too busy with my real job to spend
much time with Lua 5.  Perhaps someone else can recommend a simple
workaround?  For now, table.setn is your friend.

Gordon


Daniel Silverstone wrote:
> 
> The following behaviour seems really rather broken:
> 
> dsilvers@salmon:~/dev/betty/aranha$ lua/bin/lua
> Lua 5.0 (beta)  Copyright (C) 1994-2002 Tecgraf, PUC-Rio
> > t = {}
> > t[1] = {}
> > t[2] = {}
> > t[3] = {}
> > table.foreach(t,print)
> 1       table: 0x80708f0
> 2       table: 0x8070a70
> 3       table: 0x8070c18
> > table.remove(t,3)
> > table.foreach(t,print)
> 1       table: 0x80708f0
> 2       table: 0x8070a70
> > t[1] = {}
> > t[2] = {}
> > t[3] = {}
> > table.foreach(t,print)
> 1       table: 0x8071568
> 2       table: 0x8071690
> 3       table: 0x8071808
> > table.remove(t,3)
> > table.foreach(t,print)
> 1       table: 0x8071568
> 3       table: 0x8071808
> >
> 
> Notice how the second time I do table.remove(t,3) it removes 2 not 3
> 
> Any ideas?
> 
> D.
> 
> --
> Daniel Silverstone                               http://www.digital-scurf.org/
> Hostmaster, Webmaster, and Chief Code Wibbler          Digital-Scurf Unlimited
> GPG Public key available from keyring.debian.org               KeyId: 20687895
> Write yourself a threatening letter and pen a defiant reply.