lua-users home
lua-l archive

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

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... .

The nicely working code segment now is the following:

function GLOBAL_Lock(){
 lua_getglobal( L, "_G");              //_G on stack
 luaL_newmetatable( L, "_G"));   // new metatable on stack (and registry fine)
 lua_pushcfunction( L, lock_new_index);
 lua_setfield( L, -2, "__newindex");  // pops function from stack
(keeps metatable)
//  luaL_setmetatable( L, "_G");   //STUPID CODE! this will NOT work
  lua_setmetatable( L, -2);           // pops metatable from stack
  lua_pop( L, 1);     // _G

And here a nice/helpful code snippet to check, wheter it really has worked:

  lua_getglobal( L, pcTable);
  int iTyp= luaL_getmetafield( L, -1, cpc__newindex);
  assert( LUA_TFUNCTION== iTyp);
  lua_pop( L, 2);

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...).

On Thu, Oct 14, 2021 at 6:29 PM nobody <> wrote:
> (Re)read the documentation, getglobal looks up stuff with string keys in _G / the global environment. newmetatable takes an arbitrary name for your new metatable that has nothing to do with fields in the global environment. You could name your metatable "asdf" and exactly the same thing would happen.
> >> Have you checked what you're actually doing, on the Lua-level?
> >>>
> >>> luaL_newmetatable( L, "_G"));
> >>
> >> local temp = {} ; debug.getregistry()._G = temp
> So yes, at some point you'll have to push _G and actually set its metatable, and probably also point parts of your construction at it. (I don't get how it's supposed to work, do you make a new "shadow table" and reroute *all* nonexistent stuff over there, or do you want to mostly put stuff back into _G?)
> I strongly suggest you make it work in Lua first and then translate to C.
> -- nobody