lua-users home
lua-l archive

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


Hi,

I was wondering: what misbehaviours I should expect if I set non
event-related fields of a metatable ?
For example: I have a heavy userdata for which I set a metatable. I want to
make this userdata fit the needs of some mechanism. For this I need to
associate fields to it so that it can store some persistent information
concerning this mechanism. I cannot implement this in the userdata itself,
because I don't know which userdata is subjet to integration in the
mechanism. A way to do so is to have some global table indexed by the
userdata where the value is whatever I need to store. The userdata then has
a metatable that upon access, fetches the fields in that global table. I
need also to make sure that when the userdata is no longer referenced, the
entry disappears, which for various reasons is not trivial in my case.
Therefore, I thought to store those fields directly in the metatable, and
have in the __gettable entry of the metatable the necessary acccessors like:

>  mt={__index={readField=function(t) return getmetatable(t).field end } ,
field = 1}
> bib={a=2}
> setmetatable(bib,mt)
> print (bib.readField)
function: 002FD010
> print (bib:readField())
1
> mt.field=nil
> print (bib:readField())
nil
> mt.field=55
> print (bib:readField())
55


Is this endorsed by the language and will work as it should be expected from
any table, or is there some problem regarding a special handling of
metatables I am not aware of ?



Another question: what happens when one sets the metatable of a metatable ?
I tried this:

> t1 = { __index = { a=1}}
> t2={__index={b=2}}
> setmetatable(t1,t2)
> print (t1.b)
2
> bob={c=3}
> setmetatable(bob,t1)
> print (bob.a)
1
> print (bob.b)
nil
> print (bob.c)
3

The __gettable semantics say that I should get 2 when reading bob.b:

Since bob is a table and field b does not exist, __gettable get its
metatable t1. Since t1 is non-nil and not a function, __gettable tries to
get t1[b], which should yield 2.
Why is this not the case ? Is this a bug or a normal behaviour ? Being able
to setup that kind of things is a form of class heritage and should be
allowed, I think ?


Regards,

Benoit.