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... ).
There are definitely some things in the C API that could be named better, agreed. This is a prime example. luaL_setmetatable is rarely used though, I would guess, as for its intended purpose, luaL_newmetatable is usually simpler.
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..).
Correct, a userdata never has "valid indices" and so __index and __newindex will fire every time for a userdata. All indexing operations on userdata must pass through one of those two metamethods.
Conversely, for tables, __index and __newindex behave in the manner I described (firing only if that key does not exist or is nil).
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...
Rather than mangle the name (where the user could manually create that name and bypass your metamethods), it would be better to store them in a separate table without mangling and have the __index and __newindex functions be the only way to access that table (e.g. by closures, using lua_pushcclosure and lua_upvaluejoin). Then the "real" values would be inaccessible except through the metamethods (and the debug library, which is generally the first thing you should remove when sandboxing).
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...
I'm not sure what you're asking here? (Admittedly, I haven't read the entire thread in detail since I am currently sick with a cold, so maybe I'm missing something obvious.)