Okay so I have written one implementation but I'm getting wrong results, I'm wondering how this could be fixed?
function class(constructor, class)
constructor = constructor or {}
class = class or {}
function class:new(...)
local self = setmetatable({}, {
__index = setmetatable(class, getmetatable(self));
});
constructor(self, ...);
return self;
end
return class;
end
Rectangle = class(function(self, w, h)
self.w = w;
self.h = h;
end, { testA = 1 });
Square = class(function(self, size)
Rectangle.new(self, size, size);
end, { testB = 4 });
rect = Rectangle:new(2, 3);
square = Square:new(5, 6);
print(rect.w);
print(rect.h);
print(rect.testA);
print(rect.testB);
print(square.w);
print(square.h);
print(square.testA);
print(square.testB);
Gives me the results of 2, 3, 1, 4, nil, nil, nil, 4
And expected results of 2, 3, 4, nil, 5, 6, 1, 4
Because square inherits rectangle. And this implementation should allow chaining as many inheritances as you desire.
Edit: So I re-tried with another version but now I'm getting error at print(rect.testA); and new code:
function class(construct, namespace)
construct = construct or {};
namespace = namespace or {};
function namespace:new(...)
arg_metatable = getmetatable(self) or {};
arg_supers = arg_metatable.supers or {};
arg_supers[#arg_supers + 1] = namespace;
local self = setmetatable({}, {
supers = arg_supers;
__index = function(object, key)
for _, super in pairs(supers) do
if super[key] then return super[key] end;
end
end
});
construct(self, ...);
return self;
end
return namespace;
end
Rectangle = class(function(self, w, h)
self.w = w;
self.h = h;
end, { testA = 1 });
Square = class(function(self, size)
Rectangle.new(self, size, size);
end, { testB = 4 });
rect = Rectangle:new(2, 3);
square = Square:new(5, 6);
print(rect.w);
print(rect.h);
print(rect.testA);
print(rect.testB);
print(square.w);
print(square.h);
print(square.testA);
print(square.testB);
Edit: yet another edit with a clearer updated version, this version though gives me the same error but without even printing rect.w and rect.h which should be 2 and 3, rather I get the error about nil rather than table in code "for _, inherit in pairs(inherits) do" straight away.
function class(construct, namespace)
construct = construct or {};
namespace = namespace or {};
-- object can be a class or an instance to inherit from
namespace.new = function(object, ...)
object_metatable = getmetatable(object) or {};
object_inherits = object_metatable.inherits or {};
new_inherits = object_inherits
new_inherits[#new_inherits + 1] = namespace;
new_instance = {};
setmetatable(new_instance, {
inherits = new_inherits,
__index = function(instance, key)
for _, inherit in pairs(inherits) do
if inherit[key] then return inherit[key] end
end
end
});
return new_instance;
end
return namespace;
end
Rectangle = class(
function(self, w, h)
self.w = w;
self.h = h;
end,
{ testA = 1 }
);
Square = class(
function(self, size)
Rectangle.new(self, size, size);
end,
{ testB = 4 }
);
rect = Rectangle:new(2, 3);
square = Square:new(5, 6);
print(rect.w);
print(rect.h);
print(rect.testA);
print(rect.testB);
print(square.w);
print(square.h);
print(square.testA);
print(square.testB);
Kind Regards,
augustas656