lua-users home
lua-l archive

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


Am 16.09.2014 um 15:58 schröbte Andrew Starks:
On Tue, Sep 16, 2014 at 7:42 AM, Dirk Schippers <lua@frixx-it.com> wrote:

I don't like the Lua registry (especially because of the keys that should
be carefully chosen to not mess things up - I use a lightuserdata adressed
to some static C variable as key - ), but I think I needed it for this.

That's a reasonable way to do it (and a perfect example of where to use lightuserdata).

[...] 5.1 doesn't have `uservalue`s.

They are called "environments" in Lua 5.1. And that's what I would recommend (instead of a per-instance metatable which doesn't work with lightuserdata anyway). There is a storage hierarchy in Lua where you can store stuff:

1) Lua state local: registry (private) or globals table (public)
2) module local: function upvalues (private)
3) (userdata-)type local: metatable (public or private)
4) (userdata-)instance local: environment/uservalue (private)

Nothing prevents you from using a per-instance metatable, but there are some things in Lua that work better with a per-type metatable (e.g. some relational operators, and `luaL_checkudata` etc.). And of course you can always go one level higher by using a table with suitable keys ...

Now about those lightuserdata: I know "lightuserdata" sounds much nicer and "lighter" than full userdata, but in 90% you want full userdata. Lightuserdata are only useful/safe under very special circumstances. If used outside of those cases, they have the following problems:

1) You have to implement your own type checking (i.e. `luaL_checkudata` won't work for you). Lua can't distinguish between lightuserdata except by pointer value, so your functions must be able to determine that a lightuserdata really belongs to you by looking at the pointer value alone. 2) Lua doesn't manage the lifetime of the data pointed to by lightuserdata. That means that you can have lightuserdata to memory that's long gone, or memory that's already inaccessible by Lua (and you have no way of knowing about that).
3) Lightuserdata don't have environments/uservalues.
4) All lightuserdata share a single metatable. If you want to use more than one module which sets a metatable on lightuserdata, you are screwed. (Btw., that also means that all your windows will share the same `OnMouseMove` function!)


HTH,
Philipp