removed mentions from __index2 for now. Awaiting answers from SO regarding performance impact

This commit is contained in:
Enrique García 2010-12-05 01:17:57 +01:00
parent 1db31b3fd4
commit 7569bfe2d0

View File

@ -15,8 +15,8 @@ local _metamethods = { -- all metamethods except __index
Object = { name = "Object", __modules = {} }
Object.__classDict = {
initialize = _nilf, destroy = _nilf, subclassed = _nilf, __index2 = _nilf,
__tostring = function(instance) return ("instance of ".. instance.class.name) end -- root __tostring method
initialize = _nilf, destroy = _nilf, subclassed = _nilf,
__tostring = function(instance) return ("instance of ".. instance.class.name) end -- root of __tostring method
}
Object.__classDict.__index = Object.__classDict -- instances of Object need this
@ -27,6 +27,8 @@ setmetatable(Object, {
__tostring = function() return "class Object" end -- allows tostring(obj)
})
_classes[Object] = Object -- register Object on the list of classes.
-- creates a new instance
Object.new = function(theClass, ...)
assert(_classes[theClass]~=nil, "Use class:new instead of class.new")
@ -41,16 +43,15 @@ Object.subclass = function(theClass, name)
assert(_classes[theClass]~=nil, "Use class:subclass instead of class.subclass")
assert( type(name)=="string", "You must provide a name(string) for your class")
local theSubClass = { name = name, superclass = theClass, __classDict = { __index2=_nilf }, __modules={} }
local theSubClass = { name = name, superclass = theClass, __classDict = {}, __modules={} }
local dict = theSubClass.__classDict -- classDict contains all the [meta]methods of the class
dict.__index = dict -- It "points to itself" so instances can use it as a metatable.
local superDict = theClass.__classDict -- The superclass' classDict
-- when a method isn't found on classDict, 'escalate upwards'. If not found either, try with __index2
setmetatable(dict, { __index = function(self,x) return superDict[x] or dict.__index2(self, x) end })
setmetatable(dict, superDict) -- when a method isn't found on classDict, 'escalate upwards'.
for _,mmName in ipairs(_metamethods) do -- Creates the initial class metamethods
for _,mmName in ipairs(_metamethods) do -- Creates the initial metamethods
dict[mmName]= function(...) -- by default, they just 'look up' for an implememtation
local method = superDict[mmName] -- and if none found, they throw an error
assert( type(method)=='function', tostring(theSubClass) .. " doesn't implement metamethod '" .. mmName .. "'" )
@ -60,20 +61,19 @@ Object.subclass = function(theClass, name)
setmetatable(theSubClass, {
__index = dict, -- look for stuff on the dict
__newindex = function(_, methodName, method) -- add 'super' to methods, renaming __index to __index2
__newindex = function(_, methodName, method) -- add 'super' to methods
if type(method) == 'function' then
local fenv = getfenv(method)
local newenv = setmetatable( {super = superDict}, {__index = fenv, __newindex = fenv} )
setfenv( method, newenv )
end
if methodName == '__index' then methodName = '__index2' end -- __index becomes __index2
rawset(dict, methodName , method)
end,
__tostring = function() return ("class ".. name) end, -- allows doing tostring(MyClass)
__call = function(_, ...) return theSubClass:new(...) end -- allows doing MyClass(...) instead of MyClass:new(...)
__tostring = function() return ("class ".. name) end, -- allows tostring(MyClass)
__call = function(_, ...) return theSubClass:new(...) end -- allows MyClass(...) instead of MyClass:new(...)
})
theSubClass.initialize = function(instance,...) super.initialize(instance) end
theSubClass.initialize = function(instance,...) super.initialize(instance) end -- default initialize method
_classes[theSubClass]= theSubClass -- registers the new class on the list of _classes
theClass:subclassed(theSubClass) -- hook method. By default it does nothing
@ -93,8 +93,6 @@ Object.include = function(theClass, module, ... )
return theClass
end
_classes[Object] = Object -- register Object on the list of classes.
-- Returns true if aClass is a subclass of other, false otherwise
function subclassOf(other, aClass)
if _classes[aClass]==nil or _classes[other]==nil then return false end