function class_mro(mro, bases, cache) if bases == nil then return end for k, v in pairs(bases) do if cache[v.__name__] ~= nil then end class_mro(mro, v.__bases__, cache) end for k, v in pairs(bases) do if cache[v.__name__] == nil then table.insert(mro, v) end cache[v.__name__] = v end end function class(name, ...) local c = {} -- a new class instance local mro_bases = {} class_mro(mro_bases, {...}, {}) for i_base, base in pairs(mro_bases) do for i_arg, base_arg in pairs(base) do c[i_arg] = base_arg end end c.__name__ = name c.__bases__ = mro_bases -- the class will be the metatable for all its objects, -- and they will look up their methods in it. --c.__index = function( --c.__index = c -- expose a constructor which can be called by () local mt = {} mt.__call = function(class_tbl, ...) local obj = {} setmetatable(obj, c) obj.index = setmetatable({__name__ = "dict.index"}, { __index = function(klass, key) return obj.__getattr__(key) end , __newindex = function(klass, key, value) obj.__setattr__(key, value) end }) obj.__class__ = c for k, v in pairs(c) do if type(v) == "function" then obj[k] = setmetatable({}, { __index = function(self, key) if key == "__name__" then return str(k) else return self[key] end end , __call = function(self, ...) return v(obj, ...) end }) end end if class_tbl.__init__ then class_tbl.__init__(obj, ...) end return obj end setmetatable(c, mt) return c end