metatable abuse..

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

metatable abuse..

Francisco Olarte
Hello everyone.

When publishing some classes I have in my code to Lua I've been using
the trick of setting metatable.__index to the metatable and also
stashing some markers I use ( they are mainly light userdata derived
from the address of auxiliary static objects )

>From all I've seen / read I think it won't cause problems, and I've
seen the __index thing using in several places, and the lightuserdata
shouldn't pose a problem, as the only normal way to get at them is to
enumerate the table, but I'd like to hear if I've missed something and
I should not be storing "alien" date in there.

So, is there any problem with storing strange things in an object metatable?


Francisco Olarte.

Reply | Threaded
Open this post in threaded view
|

Re: metatable abuse..

Aaron B.
On Sat, 15 Jun 2019 21:50:41 +0200
Francisco Olarte <[hidden email]> wrote:

> So, is there any problem with storing strange things in an object metatable?

My database library SqlTable does exactly this, to prevent it's
internal state information from colliding with the keys of data within
the database.

It hasn't caused problems in Lua 5.1 through to 5.3, so it at least
works well. If it's actually a good idea... I don't know.

--
Aaron B. <[hidden email]>

Reply | Threaded
Open this post in threaded view
|

Re: metatable abuse..

Soni "They/Them" L.


On 2019-06-15 8:20 p.m., Aaron B. wrote:

> On Sat, 15 Jun 2019 21:50:41 +0200
> Francisco Olarte <[hidden email]> wrote:
>
> > So, is there any problem with storing strange things in an object metatable?
>
> My database library SqlTable does exactly this, to prevent it's
> internal state information from colliding with the keys of data within
> the database.
>
> It hasn't caused problems in Lua 5.1 through to 5.3, so it at least
> works well. If it's actually a good idea... I don't know.
>

I use

local KEY = {}
local foo = {[KEY] = {stuff}, your, data, here}

this will never conflict with something like a database. it also avoids
going through a function call to do a metatable lookup and stuff. but it
does get in the way of pairs, so if pairs is important for you then I
guess you can't use it.

Reply | Threaded
Open this post in threaded view
|

Re: metatable abuse..

Francisco Olarte
In reply to this post by Aaron B.
Aaron:

On Sun, Jun 16, 2019 at 1:21 AM Aaron B. <[hidden email]> wrote:
> Francisco Olarte <[hidden email]> wrote:
> > So, is there any problem with storing strange things in an object metatable?
> My database library SqlTable does exactly this, to prevent it's
> internal state information from colliding with the keys of data within
> the database.

I mainly use that to mark whether a wrapped object "implements" an
interface ( I have C++ object for each one and mark the metatables
with a LUD pointing to itself ( meta[klassLud]=klassLub ), which I
found easy to implement and let's me have some kind of
"inheritance"...

> It hasn't caused problems in Lua 5.1 through to 5.3, so it at least
> works well. If it's actually a good idea... I don't know.

... and I'm exactly there, just with only 5.3, but anyway, it's nice
knowing I'm not the only one having that kind of ideas ( and making
them work ). Thanks.

Francisco Olarte.



>
> --
> Aaron B. <[hidden email]>
>

Reply | Threaded
Open this post in threaded view
|

Re: metatable abuse..

Philippe Verdy
In reply to this post by Soni "They/Them" L.
That's an excellent trick, allowing to attach several independant "metatables", each one with its own unique "index" which is a reference to a table, without depending on Lua's own metatable (which works as if we had attached it as the value of an hidden/nil key of the main table).

And it is definitely easier to access fields in these metatables and make sure they will also never collide with Lua's own use of some keys that are bound to Lua's own syntax (like "__index", "__newindex", "__add"...). In most cases metatables are not needed at all, except when one effectively desires to control Lua's own behavior.

But one "bad" thing is that these extra fields keyed by table will be enumerated by `pairs()` and the code may not be prepared to get keys that are neither strings nor numbers; note that these keys will still not be returned as part of sequences enumerated by `ipairs()` whose keys are only numbers (and only positive integers).

But one problem is when you want to return *structured* data from a database (including JSON data, or using custom datatypes that cannot be simply represented by a single number or string): this trick does not work and you still need the metatable instead to store the metadata for the dataset, or you can separate the dataset (in its own table) and your metadata (also in its own table) and pack them together in a parent table with predictable keys, like:
  `{dataset={...}, metadata={query={...}, reply={status=200, msg='OK', timestamp=...}, session={uniqueid=..., commited=false, updatable=true, rollbackable=false, ...}}, ...}`
which also avoids any use of the Lua's metatable.



Le dim. 16 juin 2019 à 01:24, Soni "They/Them" L. <[hidden email]> a écrit :


On 2019-06-15 8:20 p.m., Aaron B. wrote:
> On Sat, 15 Jun 2019 21:50:41 +0200
> Francisco Olarte <[hidden email]> wrote:
>
> > So, is there any problem with storing strange things in an object metatable?
>
> My database library SqlTable does exactly this, to prevent it's
> internal state information from colliding with the keys of data within
> the database.
>
> It hasn't caused problems in Lua 5.1 through to 5.3, so it at least
> works well. If it's actually a good idea... I don't know.
>

I use

local KEY = {}
local foo = {[KEY] = {stuff}, your, data, here}

this will never conflict with something like a database. it also avoids
going through a function call to do a metatable lookup and stuff. but it
does get in the way of pairs, so if pairs is important for you then I
guess you can't use it.