[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Write metamethod
- From: Mark Hamburg <mhamburg@...>
- Date: Fri, 05 Sep 2003 12:26:16 -0700
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