function Index (t,f) if f == 'parent' then -- to avoid loop return OldIndex(t,f) end local p = t.parent if type(p) == 'table' then return p[f] else return OldIndex(t,f) end end OldIndex = setfallback("index", Index)Whenever Lua attempts to access an absent field in a table, it calls the fallback function Index. If the table has a field parent with a table value, then Lua attempts to access the desired field in this parent object. This process is repeated ``upwards'' until a value for the field is found or the object has no parent. In the latter case, the previous fallback is called to supply a value for the field.
When better performance is needed,
the same fallback may be implemented in C,
as illustrated below.
int lockedParentName; /* stores the lock index for the string "parent" */
int lockedOldIndex; /* previous fallback function */
void callOldFallback (lua_Object table, lua_Object index)
{
lua_Object oldIndex = lua_getlocked(lockedOldIndex);
lua_pushobject(table);
lua_pushobject(index);
lua_callfunction(oldIndex);
}
void Index (void)
{
lua_Object table = lua_getparam(1);
lua_Object index = lua_getparam(2);
lua_Object parent;
if (lua_isstring(index) && strcmp(lua_getstring(index), "parent") == 0)
{
callOldFallback(table, index);
return;
}
lua_pushobject(table);
lua_pushlocked(lockedParentName);
parent = lua_getsubscript();
if (lua_istable(parent))
{
lua_pushobject(parent);
lua_pushobject(index);
/* return result from getsubscript */
lua_pushobject(lua_getsubscript());
}
else
callOldFallback(table, index);
}
This code must be registered with:
lua_pushliteral("parent");
lockedParentName = lua_lock();
lua_pushobject(lua_setfallback("index", Index));
lockedOldIndex = lua_lock();
Notice how the string "parent" is kept
locked in Lua for optimal performance.