lua-users home
lua-l archive

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


On Thu, Oct 14, 2021 at 3:19 PM Flyer31 Test <flyer31@googlemail.com> wrote:
Yes, I thought this already, but it is not easy for me as I have to
combine this with my C code... .

But you are completely right somehow ... after I looked at this nice
tiny Lua code snippet  for GLOBAL_Lock (see my first post) over and
over again ... and after I read through the reference manual over and
over again, I suddenly recognized, that there are two C functions
"..._setmetatable", one is called "lua_setmetatable" (this one gets
the orginaltable from stack, so it requires to call first
lua_getglobal("_G")), and the other one is called "luaL_setmetatable"
(this one gets "_G" as argument and does NOT touch the stack...
somehow really a bit a strange c function, as most of them use the
stack for parameter transfer...).

So lua_setmetatable is the nice one, and luaL_setmetatable does NOT
work... a bit bizarre... .

luaL_setmetatable does work, but not in the way you think. The string literal argument to luaL_setmetatable is not the name of a variable to associate the metatable with. Rather, it is the **name of the metatable itself**, which is then associated with the metatable via the Lua registry and can then be used with other C API functions, often to type-check that the value passed to your function is that of a type you expect (i.e. by checking that its metatable has the name you expect. luaL_setmetatable does not actually associate the metatable with a table; you do that with lua_setmetatable.

In general, lua_* functions are the basic C API, while luaL_* functions are the auxiliary library that adds a bunch of convenience stuff, but doesn't do anything that can't be done with the basic C API.
 
Just finally I discovered, that my _G __newindex fires only on FIRST
definition of a global variable (quite clear, do not lough about me
please :( ... ).

But I would need something which fires ANY TIME a variable is written.
Best e. g. some special variable type like my strbuf with some special
metafunction, so then working also possibly for local types... but my
strbuf function practically always will be globals defined at the very
start of the program, so if it would fire only for any write access to
_G would be perfectly fine also ... . But I am frightened such a meta
does not exist... . Read instead is supported nicely (__index fires on
any read access). But __newindex fires only on new/create ... but not
on write/reassign .. I would need a sort of meta called "__change" or
"__modify" or at least "__newtype" or so ... but such things
unfortunately not available...).

 This is how __index and __newindex work: they fire only if the current value is nil. If you want __index and __newindex to fire every time, you need to set __newindex to divert all writes to another table and __index to read from that table, then set that metatable on an empty table and use that empty table as your object (essentially a proxy). However, doing this with the global environment would be tricky at best.