lua-users home
lua-l archive

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


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.