|
The below snippet from Luvit might be pretty much all OO you ever really need.
2014-02-23 3:19 GMT+01:00 Journeyer J. Joh <oosaprogrammer@gmail.com>:
| What method would be the best for OO style lua programming?
--[[
This is the most basic object in Luvit. It provides simple prototypal
inheritance and inheritable constructors. All other objects inherit from this.
]]
local Object = {}
core.Object = Object
Object.meta = {__index = Object}
-- Create a new instance of this object
function Object:create()
local meta = rawget(self, "meta")
if not meta then error("Cannot inherit from instance object") end
return setmetatable({}, meta)
end
--[[
Creates a new instance and calls `obj:initialize(...)` if it exists.
local Rectangle = Object:extend()
function Rectangle:initialize(w, h)
self.w = w
self.h = h
end
function Rectangle:getArea()
return self.w * self.h
end
local rect = Rectangle:new(3, 4)
p(rect:getArea())
]]
function Object:new(...)
local obj = self:create()
if type(obj.initialize) == "function" then
obj:initialize(...)
end
return obj
end
--[[
Creates a new sub-class.
local Square = Rectangle:extend()
function Square:initialize(w)
self.w = w
self.h = h
end
]]
function Object:extend()
local obj = self:create()
local meta = {}
-- move the meta methods defined in our ancestors meta into our own
--to preserve expected behavior in children (like __tostring, __add, etc)
for k, v in pairs(self.meta) do
meta[k] = v
end
meta.__index = obj
meta.super=self
obj.meta = meta
return obj
end
Plus maybe this, also from Luvit:
--[[
Returns whether obj is instance of class or not.
local object = Object:new()
local emitter = Emitter:new()
assert(instanceof(object, Object))
assert(not instanceof(object, Emitter))
assert(instanceof(emitter, Object))
assert(instanceof(emitter, Emitter))
assert(not instanceof(2, Object))
assert(not instanceof('a', Object))
assert(not instanceof({}, Object))
assert(not instanceof(function() end, Object))
Caveats: This function returns true for classes.
assert(instanceof(Object, Object))
assert(instanceof(Emitter, Object))
]]
function instanceof(obj, class)
if type(obj) ~= 'table' or obj.meta == nil or not class then
return false
end
if obj.meta.__index == class then
return true
end
local meta = obj.meta
while meta do
if meta.super == class then
return true
elseif meta.super == nil then
return false
end
meta = meta.super.meta
end
return false
end