lua-users home
lua-l archive

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


Yeah I am starting to wonder whether altering setmetatable is the best solution. I do have control over the entire program. It's just a big step to take, so I want to explore alternatives first. :-)

On Mon, Oct 15, 2012 at 6:58 PM, Coda Highland <chighland@gmail.com> wrote:
 Can you not change the code in realmetatable to alter _mymt instead?
Alternatively, you could use some setfenv/_ENV magic to change out
setmetatable() for the functions that matter without screwing up the
rest of the state.

/s/ Adam

On Mon, Oct 15, 2012 at 3:51 PM, Marc Lepage <mlepage@antimeta.com> wrote:
> 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...
>> >> >
>> >> >
>> >>
>> >
>>
>