[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Problems when traversing tables.
- From: Edgar Toernig <froese@...>
- Date: Tue, 15 May 2001 01:30:12 +0200
Joakim Hansson wrote:
>
> Maybe this is a trivial question, but I have spent quit a lot of
> time trying to solve the following seemingly uncomplicated task:
> I have a LUA program that looks like this:
>[...]
Some points you should take care of:
1) lua_getglobal takes a simple strings and returns the
value of the global variable with that name. It does
_not_ interpret dots or other special chars. So if
you call getglobal("foo.bar.baz") you get the value of
the var named "foo.bar.baz" (will most likely not exist).
To access fields from a global table you have to write
something like:
lua_getglobal(L, "foo");
lua_pushstring(L, "bar");
lua_gettable(L, -2); // -1 is "bar", -2 is foo
lua_pushstring(L, "baz");
lua_gettable(L, -2); // -1 is "baz", -2 is foo.bar
// stack is: -1 foo.bar.baz -2 foo.bar
lua_remove(L, -2); // remove foo.bar, just keep foo.bar.baz
2) Lua does automatic string/number conversions in a lot of
places. There are 2 subtle side effects: first, lua_tostring
converts the addressed stack location if it contains a
number (similar for tonumber). So,
lua_pushnumber(L, 3.14);
printf("%s\n", lua_typename(L, lua_type(L, -1))); // --> number
(void)lua_tostring(L, -1);
printf("%s\n", lua_typename(L, lua_type(L, -1))); // --> string
Second, accessing a table does _not_ perform type conversion.
So, a[0] accesses a different element than a["0"].
Together these two effects sometimes create a lot of confusion.
A really nasty one is when trying to scan tables with lua_next.
It requires a key on the stack. If nil it starts at the beginning
of the table, if non-nil it gives the next entry after the
given key.
If you try to print the current key (using lua_tostring) and it
was a number (i.e. because the table was { "a", "b", "c" }),
you've just converted the key on the stack to a string. The
next lua_next call will try to find the previous key and fails
because you just converted it to a string. -->Run time error.
[Unfortunately the manual gives an example that gets caught by
this side effect.]
Your readTable code prints the key and so is unable to scan over
numeric tables (lists).
3) You should try to remember what's on the stack ;-)
And then, Lua's tables are pretty fast. Trying to copy tables into
linear lists (findKey) is kind of . . . strange ;-)
Ciao, ET.
PS: Another thing worth mentioning. Afaik it's undocumented but
IMHO making it a "documented feature" would be nice.
String pointers you get from Lua stay valid as long as they are
used within Lua. So if you get a string from a table and you don't
destroy the table the pointer stays valid.
And more, strings are unique. The same strings will always return
the same pointer. If two string pointers returned from Lua are equal,
the strings are equal (and vice versa, if unequal the strings are
unequal). So there's no need to strdup strings if you don't
destroy the Lua structures holding them.