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.
#include "lua.h"
int lockedParentName; /* lock index for the string "parent" */
int lockedOldIndex; /* previous fallback function */
void callOldFallback (lua_Object table, lua_Object index)
{
lua_Object oldIndex = lua_getref(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_pushref(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_pushstring("parent");
lockedParentName = lua_ref(1);
lua_pushobject(lua_setfallback("index", Index));
lockedOldIndex = lua_ref(1);
Notice how the string "parent"
is kept
locked in Lua for optimal performance.