[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Install __newindex for _G in C
- From: Flyer31 Test <flyer31@...>
- Date: Thu, 14 Oct 2021 22:33:15 +0200
Thanks - no comment to lua_setmetatable and luaL_setmetatable - this
really is awkward, but things like this sometimes happen in large
systems/documentations (and in Lua this is the first REALLY awkward
naming I encounter... of course somehow impossible to correct now, I
understand this... ).
Concerning __index and __newindex thank you for your enlightening
comment ... . Concerning __index this was not really clear to me ...
but my strbuf userdata clearly IS something which you call proxy... as
it has no real indices... it just uses this writing to fire __index /
__newindex (but I think userdata very typically will do something like
this in most cases..).
Concerning the _G table I really could consider to use this, E.g. if
__newindex is fired for a key starting with "Buf...", then in my
__newindex function I would extend it to __strbuf__Buf..., , so then
__newindex and __index will fire any time, Buf... is accessed... . But
maybe I should better sleep over this, whether I really want to do
this ... but it is somehow quite a smart and possible idea I think...
.
Would you have a hint, how to fire an error, if a user then tries to
produce a local strbuf variable? (this really would not make too much
sense ... the main advantage of this strbuf buffers is the malloc only
ONCE, but if you use them locally, you can as well work just with
strings I think...). So somehow my userdata strbuf __index/ __newindex
functions should be able to check, whether they are in the _G table,
but this really is very straight forward...
... thank you for this helpful thinking...
On Thu, Oct 14, 2021 at 9:37 PM Jonathan Goble <jcgoble3@gmail.com> wrote:
>
> 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.