lua-users home
lua-l archive

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


OK I see.

In that case, the problem is that at some point, realmetatable will change the object's metatable to realmetatable2, so metametatable won't be in effect anymore. What I really wanted to happen is to intercept that and install metametatable2 around realmetatable2.

I have also tried the approach like below, where metametatable is realmetatable, and _mymt is the extras I want to add. But that requires altering realmetatable (so it looks into _mymt for extensions).


On Mon, Oct 15, 2012 at 6:11 PM, Coda Highland <chighland@gmail.com> wrote:
What I meant is something like:

metametatable = {
  __index = function(tbl, key) return tbl._mymt.__index(tbl, key) end,
  -- etc.
}

You then setmetatable(obj, metametatable); obj._mymt = realmetatable;
to get the behavior you would have gotten originally. This allows you
to change how metatables work by changing the implementation in
metametatable.

/s/ Adam

On Mon, Oct 15, 2012 at 2:48 PM, Marc Lepage <mlepage@antimeta.com> wrote:
> You mean, a metatable reaches back into the object to look for fields, in
> certain cases? Yeah, I prototyped that and it works. That's what I meant in
> my original post, about adding extension hooks to the metatable. It means
> that client code has to be careful to edit the hooks and not the metatable
> directly. I might end up having to do it that way, but I'm investigating
> alternatives.
>
> Or, is this technique slightly different than I am thinking?
>
>
> On Mon, Oct 15, 2012 at 5:17 PM, Coda Highland <chighland@gmail.com> wrote:
>>
>> Wouldn't a meta-metatable be less invasive for this kind of thing?
>> Have a singular metatable that you assign to everything you care about
>> that delegates its behaviors to an element of the table it's assigned
>> to.
>>
>> I suppose performance might be somewhat lower, if you get a LOT of
>> metatable accesses, but it wouldn't be all that hard.
>>
>> /s/ Adam
>>
>> On Mon, Oct 15, 2012 at 2:12 PM, Marc Lepage <mlepage@antimeta.com> wrote:
>> > Yeah, it's just that being notified of setmetatable would facilitate
>> > using
>> > metatables to build state machines (getting notification of the state
>> > change), and wrapping metatables allows states to be composed, but the
>> > notification is also necessary for maintaining the wrapping.
>> >
>> >
>> > On Mon, Oct 15, 2012 at 5:05 PM, Rena <hyperhacker@gmail.com> wrote:
>> >>
>> >> On 2012-10-15 4:50 PM, "Marc Lepage" <mlepage@antimeta.com> wrote:
>> >> >
>> >> > I'm wondering if there's a good way to know if a metatable for an
>> >> > object
>> >> > is changed.
>> >> >
>> >> > Suppose the case is that the metatable is not protected. An object
>> >> > wants
>> >> > to wrap its metatable with another, so it can be extended. But if the
>> >> > metatable is changed, it needs to re-wrap it.
>> >> >
>> >> > Is there a good way the object can know when that occurs, so it can
>> >> > perform the re-wrapping?
>> >> >
>> >> > I thought of re-writing setmetatable to perform a notification. I
>> >> > guess
>> >> > that would work, but it seems heavy-handed.
>> >> >
>> >> > I thought of requiring clients to call a different function that does
>> >> > the notification (or even the wrapping), but that requires editing
>> >> > clients.
>> >> >
>> >> > It would be cool if objects could implement __setmetatable, which
>> >> > would
>> >> > be called if available, when the metatable is set. It would
>> >> > effectively
>> >> > replace __metatable, because you could always just ignore it (do
>> >> > nothing) if
>> >> > you don't want the metatable to be changeable.
>> >> >
>> >> > Does anyone have advice on this topic? Thanks.
>> >>
>> >> Wrapping setmetatable to call some type of notification metamethod on
>> >> the
>> >> old metatable before applying the new one seems like the best idea.
>> >> Then you
>> >> can do things like filter or modify the new metatable (have the
>> >> notification
>> >> method take the new table as parameter and return a value that then
>> >> gets set
>> >> as the new metatable), while client code doesn't need to know anything
>> >> about
>> >> it.
>> >>
>> >> Of course when you modify a global/standard method you have to consider
>> >> modules loaded earlier that might keep a local reference,
>> >> lua_setmetatable,
>> >> and potential client headache when they aren't aware of the new
>> >> behaviour...
>> >
>> >
>>
>