[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Possible to add methods in Lua to metatables defined in C?
- From: William Ahern <william@...>
- Date: Thu, 3 May 2012 12:18:30 -0700
On Thu, May 03, 2012 at 11:46:19AM -0400, Andrew Budd wrote:
> Bear with me if I'm misunderstanding something.
>
> I have written a lua library in C, and am using metatables for methods.
> What I would like to do is add additional methods to those metatables from
> Lua. The issue seems to be that I can't access the handle for the
> metatable, and even if I could, it's not clear that I would be able to add
> a function to the table. Am I barking up the wrong tree here? or am I
> missing something obvious?
>
I usually add a special routine, "interpose", which allows adding methods to
a class. It resides in the same table as the constructor for the object. In
the following example, interpose takes 2 or 3 arguments. In the 2 argument
form it just takes a method name and a function, stores the function in the
metatable, and returns the previous entry (which might be stored in a local
variable so it can be called by the new routine). The 3 argument form takes
an additional class name as the MIME library I'm wrapping has subclasses for
headers, entities, etc, but no other way to directly access a constructor
for those classes.
static int lm_interpose(lua_State *L) {
enum lm_class type;
switch (lua_gettop(L)) {
case 2:
type = LM_MIME;
break;
case 3:
type = lm_checkclass(L, 1);
break;
default:
return luaL_error(L, "internal MIME error: wrong number of arguments (%d) to interpose", lua_gettop(L));
} /* switch(top) */
luaL_getmetatable(L, lm_strclass(type));
lua_getfield(L, -1, "__index");
lua_pushvalue(L, -4); /* push method name */
lua_gettable(L, -2); /* push old method */
lua_pushvalue(L, -5); /* push method name */
lua_pushvalue(L, -5); /* push new method */
lua_settable(L, -4); /* replace old method */
return 1; /* return old method */
} /* lm_interpose() */
static const luaL_Reg lm_globals[] = {
{ "open", &lm_open },
{ "interpose", &lm_interpose },
{ NULL, NULL }
}; /* lm_globals[] */