mirror of
https://github.com/kikito/middleclass.git
synced 2024-11-25 02:44:20 +00:00
MiddleClass: fixed nonworking implicit instantiation (Object() instead of Object:new())
This commit is contained in:
parent
b9248f5cc1
commit
df05036c61
100
MiddleClass.lua
100
MiddleClass.lua
@ -7,69 +7,69 @@
|
|||||||
local classes = setmetatable({}, {__mode = "k"}) -- weak table storing references to all declared classes
|
local classes = setmetatable({}, {__mode = "k"}) -- weak table storing references to all declared classes
|
||||||
|
|
||||||
-- The 'Object' class
|
-- The 'Object' class
|
||||||
Object = { name = "Object",
|
Object = { name = "Object" }
|
||||||
|
|
||||||
-- creates a new instance
|
-- creates a new instance
|
||||||
new = function(class, ...)
|
Object.new = function(class, ...)
|
||||||
assert(classes[class]~=nil, "Use class:new instead of class.new")
|
assert(classes[class]~=nil, "Use class:new instead of class.new")
|
||||||
|
|
||||||
local instance = setmetatable({ class = class }, class.__classDict) -- the class dictionary is the instance's metatable
|
local instance = setmetatable({ class = class }, class.__classDict) -- the class dictionary is the instance's metatable
|
||||||
instance:initialize(...)
|
instance:initialize(...)
|
||||||
return instance
|
return instance
|
||||||
end,
|
end
|
||||||
|
|
||||||
-- creates a subclass
|
-- creates a subclass
|
||||||
subclass = function(superclass, name)
|
Object.subclass = function(superclass, name)
|
||||||
assert(classes[superclass]~=nil, "Use class:subclass instead of class.subclass")
|
assert(classes[superclass]~=nil, "Use class:subclass instead of class.subclass")
|
||||||
if type(name)~="string" then name = "Unnamed" end
|
if type(name)~="string" then name = "Unnamed" end
|
||||||
|
|
||||||
local theClass = { name = name, superclass = superclass, __classDict = {} }
|
local theClass = { name = name, superclass = superclass, __classDict = {} }
|
||||||
local classDict = theClass.__classDict
|
local classDict = theClass.__classDict
|
||||||
|
|
||||||
-- This one is weird. Since:
|
-- This one is weird. Since:
|
||||||
-- a) the class dict is the instances' metatable (so it must have an __index for looking up the methods) and
|
-- a) the class dict is the instances' metatable (so it must have an __index for looking up the methods) and
|
||||||
-- b) The instance methods are in the class dict itself, then ...
|
-- b) The instance methods are in the class dict itself, then ...
|
||||||
classDict.__index = classDict
|
classDict.__index = classDict
|
||||||
-- if a method isn't found on the class dict, look on its super class
|
-- if a method isn't found on the class dict, look on its super class
|
||||||
setmetatable(classDict, {__index = superclass.__classDict} )
|
setmetatable(classDict, {__index = superclass.__classDict} )
|
||||||
-- theClass also needs some metamethods
|
-- theClass also needs some metamethods
|
||||||
setmetatable(theClass, {
|
setmetatable(theClass, {
|
||||||
__index = function(_,methodName)
|
__index = function(_,methodName)
|
||||||
local localMethod = classDict[methodName] -- this allows using classDic as a class method AND instance method dict
|
local localMethod = classDict[methodName] -- this allows using classDic as a class method AND instance method dict
|
||||||
if localMethod ~= nil then return localMethod end
|
if localMethod ~= nil then return localMethod end
|
||||||
return superclass[methodName]
|
return superclass[methodName]
|
||||||
end,
|
end,
|
||||||
-- FIXME add support for __index method here
|
-- FIXME add support for __index method here
|
||||||
__newindex = function(_, methodName, method) -- when adding new methods, include a "super" function
|
__newindex = function(_, methodName, method) -- when adding new methods, include a "super" function
|
||||||
if type(method) == 'function' then
|
if type(method) == 'function' then
|
||||||
local fenv = getfenv(method)
|
local fenv = getfenv(method)
|
||||||
local newenv = setmetatable( {super = superclass.__classDict}, {__index = fenv, __newindex = fenv} )
|
local newenv = setmetatable( {super = superclass.__classDict}, {__index = fenv, __newindex = fenv} )
|
||||||
setfenv( method, newenv )
|
setfenv( method, newenv )
|
||||||
end
|
end
|
||||||
rawset(classDict, methodName, method)
|
rawset(classDict, methodName, method)
|
||||||
end,
|
end,
|
||||||
__tostring = function() return ("class ".. name) end,
|
__tostring = function() return ("class ".. name) end,
|
||||||
__call = theClass.new
|
__call = Object.new
|
||||||
})
|
})
|
||||||
-- instance methods go after the setmetatable, so we can use "super"
|
-- instance methods go after the setmetatable, so we can use "super"
|
||||||
theClass.initialize = function(instance,...) super.initialize(instance) end
|
theClass.initialize = function(instance,...) super.initialize(instance) end
|
||||||
|
|
||||||
classes[theClass]=theClass --registers the new class on the list of classes
|
classes[theClass]=theClass --registers the new class on the list of classes
|
||||||
|
|
||||||
return theClass
|
return theClass
|
||||||
end,
|
end
|
||||||
|
|
||||||
-- Mixin extension function - simulates very basically ruby's include(module)
|
-- Mixin extension function - simulates very basically ruby's include(module)
|
||||||
-- module is a lua table of functions. The functions will be copied to the class
|
-- module is a lua table of functions. The functions will be copied to the class
|
||||||
-- if present in the module, the included() method will be called
|
-- if present in the module, the included() method will be called
|
||||||
includes = function(class, module)
|
Object.includes = function(class, module)
|
||||||
assert(classes[class]~=nil, "Use class:includes instead of class.includes")
|
assert(classes[class]~=nil, "Use class:includes instead of class.includes")
|
||||||
for methodName,method in pairs(module) do
|
for methodName,method in pairs(module) do
|
||||||
if methodName ~="included" then class[methodName] = method end
|
if methodName ~="included" then class[methodName] = method end
|
||||||
end
|
|
||||||
if type(module.included)=="function" then module:included(class) end
|
|
||||||
end
|
end
|
||||||
|
if type(module.included)=="function" then module:included(class) end
|
||||||
|
end
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
classes[Object]=Object -- adds Object to the list of classes
|
classes[Object]=Object -- adds Object to the list of classes
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user