lua-users home
lua-l archive

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


Am 10.10.2015 um 08:22 schröbte linuxfan@tin.it:
Hi list,

Hi!


[...]

This creates a Lua table named "env". If a script tries to read a
value from table env:

print (env.screenwidth)

lua nicely calls my routine xl_getxtable()
with two arguments - the table and the key.
My problem is that I don't know how to get the table name lua refers
to; while the key is passed as a string, the table is passed as a lua
internal variable which means nothing to me. I tried to search around
in examples, docs, and so on, but with no success. I only discovered
the Registry where, may be, I can store the table as key and its name
as value, so I can later fetch the name of the table.


You could just store a name in the `env` table you create and look it up in your `__index`/`__newindex` functions. To prevent collisions with the normal keys you should use a non-string key (like a boolean or a number) for this though. Your registry idea is better, because it naturally prevents such collisions, and it is safer because the registry is inaccessible from non-debug Lua code.

Probably I will end up using different xl_getxtable() functions, each
one with its hard-coded table name inside; it would be faster and the
tables to export are not so many. But while am at it, I want to
understand.

This should work as well. You can even share the same code for all your different `__index` functions by storing the name in an upvalue. Instead of `lua_pushcfunction(L, xl_getxtable)` just use

    lua_pushstring(L, name);
    lua_pushcclosure( L, xl_getxtable, 1);

and access the name inside `xl_getxtable` using `lua_upvalueindex(1)`. Downside is that you need a different metatable for each pascal table you want to export. Also, I'm not sure that having a name as a string will help you much with selecting the correct table on the pascal side. You need something like a pascal symbol name, not a string. The closest thing you can get is a pointer. You could just take the addresses of your pascal maps and push lightuserdata instead of a string name. However, the most common solution would probably be to replace your `env` table with a pointer-sized full userdata which stores the address of a pascal table inside. This address is protected from Lua code, you can easily and efficiently access the pascal table from your `__index`/`__newindex` functions, and you can share the same metamethods and metatable for all your pascal tables you want to export.


Regards,
Linuxfan


HTH,
Philipp