lua-users home
lua-l archive

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


For some structures, it is really useful to have a write metamethod that is
always called rather than only being called when the index isn't present.
Userdata already provides this, but tables don't. So, I set out to implement
one for tables. My intended semantics were that if a table had a __write
metamethod, this would be called for any non-raw set operations performed on
the table.

I would change userdata to do the same thing, but that would break existing
semantics if I replaced __newindex with __write and adds extra overhead if I
test for both.

My experiments indicated that all I seemed to need to do was:

1. Add TM_WRITE after TM_NEWINDEX in ltm.h. (Actually, it could go anywhere
before TM_EQ.)

2. Add "__write" to the corresponding table in ltm.c.

3. Make the following change to luaV_settable in lvm.c:

    TObject *oldval = luaH_set(L, h, key); /* do a primitive set */

Becomes:

    TObject *oldval;
    tm = fasttm(L, h->metatable, TM_WRITE);
    if(tm != NULL) {
        if(!ttisfunction(tm))
            luaG_typeerror(L, t, "call write metamethod for");
        callTM(L, tm, t, key, val);
        return;
    }
    oldval = luaH_set(L, h, key); /* do a primitive set */

(If not for C's declaration rules, it would be a simple insertion.)

Is that really all there is to it? If so, this was stunningly easy.

Mark