I want to do some object-oriented programming in Lua, and I decided on something like this:
local B = {} -- in real life there is other stuff in B
B.Object = {
constructor = function() end,
extend = function(this, that, meta)
if not that then that = {} end
if not meta then meta = {} end
meta.__index = this
setmetatable(that, meta)
return that
end,
isa = function(this, that)
for meta in function() return getmetatable(this) end do
if this == that then return true end
this = meta.__index
end
return this == that
end,
new = function(this, ...)
local that = this:extend()
that:constructor(...)
return that
end,
}
All objects (including "class-like objects") extend B.Object
, directly or indirectly. For example:
-- Request handler base
B.RequestHandler = B.Object:extend()
-- override these
function B.RequestHandler:accept() error "not implemented" end
function B.RequestHandler:process() error "not implemented" end
-- URL-encoded POST handler
B.PostHandler_URLEncoded = B.RequestHandler:extend()
function B.PostHandler_URLEncoded:accept()
return self.method == "POST" and
self.content_type == "application/x-www-form-urlencoded"
end
function B.PostHandler_URLEncoded:process()
-- some code
end
-- Multipart POST handler
B.PostHandler_Multipart = B.RequestHandler:extend()
-- etc.
It might be used something like this:
B.request_handlers = {
GetHandler:new(),
URLEncodedPostHandler:new(),
MultipartPostHandler:new(),
}
B.handle_request = function()
for k, v in ipairs(B.request_handlers) do
if v:accept() then
return v:process()
end
end
error "request not handled"
end
As far as I know, this is pretty much the normal way to handle inheritance in Lua. Did I miss anything? Is there anything that needs improvement?