How to Use Metatables to Accomplish Complex Tasks
With a Brief Intro to Abstractions
FILE1: class.lua
local BaseClass = setmetatable({},{
__class = true,
__type = "class",
__parent = {},
__index = BaseFunction,
__newindex = BaseFunction,
__call = BaseFunction,
__gc = BaseFunction,
__metatable = true
})local BaseIndex = function(self,index)
local parent = rawget(self,"__parent")
if (index == "super")
then return rawget(parent,"__call")
end
return parent[index]
endClass = setmetatable({},{
__class = true,
__type = "class",
__parent = BaseClass,
__index = BaseIndex,
__newindex = BaseFunction,
__call = function(self,tClass,sType,cParent,fnCall,fnGC,fnIndex,fnNewIndex)
tClass = (tClass or {})
sType = (sType or "class")
cParent = (cParent or BaseClass)
fnCall = (fnCall or BaseFunction)
fnGC = (fnGC or BaseFunction)
fnIndex = (fnIndex or BaseIndex)
fnNewIndex = (fnNewIndex or BaseFunction)
if (type(tClass) ~= "table")
or (type(sType) ~= "string")
or (not rawget(cParent,"__class"))
or (type(fnCall) ~= "function")
or (type(fnGC) ~= "function")
or (type(fnIndex) ~= "function")
or (type(fnNewIndex) ~= "function")
then
error("class: invalid args")
end
return setmetatable(tClass,{
__class = true,
__type = sType,
__parent = cParent,
__index = fnIndex,
__newindex = fnNewIndex,
__call = fnCall,
__gc = fnGC,
__metatable = true
})
end,
__gc = BaseFunction,
__metatable = true
})local oldtype = type
type = function(obj)
return (rawget(obj,"__type") or oldtype(obj))
endPART1: So what does this all mean?
The classes we create are just tables with strategically defined metamethods. The library-defined metamethods used are as follows:
- __index: called when a table is referenced with an index equal to nil
- __newindex: called when attempting to add an index to a table
- __call: called when a table is called like a function
- __gc: called when a table is garbagecollected
- __metatable: hides the metatable
- __class: a boolean flag that signifies a class object
- __type: a string that is a class' type
- __parent: a pointer to the parent of a class
TO DO: continue the tutorial