@Jmv38 - @toadkick is right, even with metatable you will fall into circular reference. I take a jump into the exercise, thank you for the break
I think you will see your ācode architectureā differently with metatables in mind, and maybe never use class anymore
My heavy loaded attempt:
-- hooked into class but can be applied 'by hand' on each
-- class instances ie:
-- A = class()
-- B = class(A)
-- b = B()
-- b.super = notsuper(A)
function notsuper(t,base)
local proxy,sp = {},{}
local function apply(self,base,k,...)
local fn = proxy[k] == base[k] and base._base[k] or base[k]
local a = {...}
return
function()
proxy[k] = fn
local res = {fn(self,unpack(a))}
proxy[k] = base[k]
return unpack(res)
end
end
sp.__index = function(tbl,k,...)
return apply(t,base,k,...)
end
return setmetatable({},sp)
end
-- override object instanciation
local oclass = class
class = function(base)
local c = oclass(base)
if not base then return c end
local mt = getmetatable(c)
mt.__call = function(class_tbl, ...)
local obj = {}
setmetatable(obj,c)
if class_tbl.init then
class_tbl.init(obj,...)
else
if base and base.init then
base.init(obj, ...)
end
end
-- > here < --
obj.super = notsuper(obj,base)
return obj
end
return c
end
function setup()
A = class()
function A:fn()
print("A called from",self)
return "A.fn called"
end
B = class(A)
function B:fn()
print("B called from",self)
return self.super:fn()
end
C = class(B)
function C:fn()
print("C called from ",self)
return self.super:fn()
end
local a = A()
print("a", a)
local str = a:fn()
print(str)
print("----------")
local b = B()
print("b", b)
local t0 = os.clock()
local str = b:fn()
local t1 = os.clock()
print(str)
print(t1-t0)
print("----------")
local c = C()
print("c", c)
t0 = os.clock()
str = c:fn()
t1 = os.clock()
print(str)
print(t1-t0)
end