Next: 7.5 A CFunction Up: 7 Some Examples Previous: 7.3 Persistence

7.4 Inheritance

The fallback for absent indices can be used to implement many kinds of inheritance in Lua. As an example, the following code implements single inheritance:
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.


Next: 7.5 A CFunction Up: 7 Some Examples Previous: 7.3 Persistence