lua-users home
lua-l archive

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

Hi list (or table?)!

I'm still evaluating how to expose my pascal 
tables to lua scripts.
So far, I understand that I have to use 
metatables linked to a table or to userdata. On the argument the manual 
is a bit ambiguous; it says "Tables and full userdata have individual 
metatables [other types share a metatable per type]". If all light 
userdata share the same metatable, I could have problems in the future. 
Moreover, I am not sure that lua scripts can "subscript" a light 
userdata the same way as a table. Supposing that I create a few global 
variables named "env", "gui"..., all of type light userdata, and I link 
a metatable on them, can I write in lua

	env.language = "en"
	if gui.
touch = "up" then ... end
and so on? If yes, this could be the way, 
but what if I will need more classes and/or different tables? Full 
metadata could do, if they behave like light userdata (if light 
userdata do what I want). I could store my pointers in the memory 
allocated by lua - no problem. So, what I want to know is the question 
above, plus some warning about difficulties I am not aware of. 
Remember, main storage must be done in host application, not scripts. 
Some tables will be read-only, some other will have special processing 
(rising events when accessed), and so on. But I must add that I am not 
afraid about scripts doing wrong things. Scripts will have to comply 
with a series of rules (for example, NOT change the metatable 
associated with host values).

I would like to add some thoughts on 
your comments. Dirk said that Lua doesn't really know the name of a 
table it pushes on the stack. But if I create a table and assign it a 
name via lua_setglobal(), that table has a name, and lua knows it 
(because lua translates the source code in byte code through the name 
of that table). I think that if a table named "env" exists,

	env2 = 
will point to the same table, so it will have the same internal 
"pointer", and the same metatable; the global table will still contain 
a link from "env" to the pointer value, and one more link "env2" with 
the same value. I could even scan the whole global table and get the 
name from the pointer (not efficient, ok). This is where the lua manual 
is a little ambiguous; it says that "every value can have a metatable", 
but what about two identical values?

Anyway, I made a quick try 
storing the lua value for my just created tables, and they work as 
expected. Dirk said that this is not a good idea, because lua doesn't 
assure the pointer stays valid, perhaps after a garbage collection. I 
don't see why lua should move a table to a different address, while 
there are global variables referencing that table, but who knows. In 
this case, all the ideas about storing the lua value somewhere (the 
registry included) fail. A __index host function should only rely on 
the table value it has got on the stack, but it could look up a key -
inside- that table. The only problem is that a lua script could modify 
that value, but my lua scripts *should not* do it.
This idea was from 
Philipp, and I want to say that is a quick and easy one; I am not 
concerned about collisions: table keys are "well known" keys, and it 
would be an error to access other keys.

After talking about light 
userdata (see my question before), Dirk talks about freepascal. Yes, my 
project uses Delphi *and* freepascal. Actually, I took the freepascal 
bindings and they work nicely under delphi.

Rena offered 4 ways.
Store the table name in the metatable). Nice and straightforward, I 
have to think about it.

(2 Map a value->tablename in the registry). 
Doesn't work if it is true that reference to a table can become 

(3 Keep the name in an upvalue). I've still to understand 
what an upvalue is. If upvalues are contexts for closures, then it is 
another nice solution to think about.

(4 Use userdata instead). I must 
investigate userdata, I suspect that they are not perfect for what I 
want. It was subtle the mention to C switch statement, as Boris also 
did. I will have no more than 8-9 tables, so any switch statement is 
faster than a lookup in a lua table.

After having received a reply to 
my question at the beginning (how compares a metatable attached to a 
userdata instead of attached to a table), I will go ahead and will let 
you know.

Salutations again, sorry for the long message,