Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lua C API register fallback __index

Tags:

c

lua

I would like to know how I can write something like this Lua Snippet from http://lua-users.org/wiki/MetamethodsTutorial

local func_example = setmetatable({}, {__index = function (t, k)
  return "key doesn't exist"
end})

local fallback_tbl = setmetatable({
  foo = "bar",
  [123] = 456,
}, {__index=func_example})

local fallback_example = setmetatable({}, {__index=fallback_tbl})

print(func_example[1]) --> key doesn't exist
print(fallback_example.foo) --> bar
print(fallback_example[123]) --> 456
print(fallback_example[456]) --> key doesn't exist

in the lua C api. I.e. I want lua to first check whether a key is in a members metatable and otherwise call the __index implementation. I have come up with something like this:

static const struct luaL_reg
lobj_fallback[] = {
    {"__index", lobject_index},
    {"__newindex", lobject_newindex},
    {"__tostring", lobject_tostring},
    {NULL, NULL}, 
};

static const struct luaL_reg
lobj_members[] = {
    {"delete", lobject_delete},
    {NULL, NULL}
};

{
    // ....
    luaL_newmetatable(L,  "MyMetaTable");
    luaL_register(L, NULL, lobj_members);

    luaL_newmetatable(L, "MyMetaTableFallback");
    luaL_register(L, NULL, lobj_fallback);

    lua_setmetatable(L, -2);
    // ...
}

Yet this does not work as expected, processing the fallback __index works but not the members metatable ("attempt to call method 'delete' (a nil value)").

like image 242
wirrbel Avatar asked Jun 24 '26 00:06

wirrbel


1 Answers

If your intention is to fallback to the indexing function when accessing "MyMetaTable", then you have swapped the names of your table and metatable. Thus the members table (lobj_members) becomes called "MyMetaTableFallback" and the metatable (lobj_fallback) becomes called "MyMetaTable".

like image 150
spbnick Avatar answered Jun 26 '26 15:06

spbnick



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!