1

I've got a userdata object I've created. I've defined the object like this:

static const luaL_Reg object_methods[] = {
    {"__gc",       pbject_gc},
    {"__tostring", object_print},
    { NULL, NULL }
};

static int
object_new (lua_State *L)
{
    Object *Object = lua_newuserdata(L, sizeof(Object));
    luaL_getmetatable(L, "Object");
    lua_setmetatable(L, -2);
    return 1;
}

int 
luaopen_Object (lua_State *L)
{
    /* create metatable */
    luaL_newmetatable(L, "Object");

    /* metatable.__index = metatable */
    lua_pushvalue(L, -1);
    lua_setfield(L, -1, "__index");

    /* register methods */
    luaL_setfuncs(L, object_methods, 0);

    /* Push a function: Object(...) => new Object */
    lua_pushcfunction(L, object_new);

    return 1;
}

I want to make a different object_new, let's say object_s_new for 'special new'. In object_s_new, how do inject a method into the object metatable?

I've tried just calling luaL_getmetatable and editing that table, but, as I expected, that edits the metatable for all objects using it. I want the injected method to be local to just objects created by object_s_new.

Is there anyway to do this without creating a completely separate metatable? Does that affect identity in any weird way with Lua? For instance, can I have a single struct Script as two different userdata types?

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Leroy
  • 237
  • 2
  • 12
  • 1
    If you want to just inject the method into an object *instance*, you don't need the metatable at all. Just set a regular field on it. – Bartek Banachewicz Oct 05 '15 at 14:59
  • 2
    @BartekBanachewicz The object is a userdata. The only way to set fields on it is via a metatable. He'll probably need a new metatable, or have to change his `__index` handler to a function so he can put some conditional logic in the message routing. – Mud Oct 05 '15 at 15:50
  • 2
    You can use chain of two metatables. – Egor Skriptunoff Oct 05 '15 at 19:10

0 Answers0