'Calling method of base class in inheritance chanin in Lua

This is a question about calling method shared by a class and its base class, and the base class of its base class.

This is the code sample

local Base = {} -- inheriting root
Base.base = nil -- base class of current class

function Base:New()
    self.__index = self
    return setmetatable({}, self)
end

---------------------------
local Person = setmetatable({}, Base)
Person.base = Base

function Person:New()
    local this = self.base.New(self)
    -- ...
    return this
end


---------------------------
local Student = setmetatable({}, Person)
Student.base = Person

function Student:New()
    local this = self.base.New(self)
    -- ...
    return this
end

If I do local s = Student:New(), I will run into an infinite recursion. Caused by self.base.New(self).

self.base.New is New method of Person, now with local self set to Student class table. And will again, call self.base.New(self). And this goes infinitely.

In the case of constructor, that self is unnecessary, and can be replaced by

self.__index = self
local this = setmetatable(self.base:New(), self)

But its actually needed some times. For example,

Foo = { a = false }
Foo.__index = Foo
function Foo:CleanUp()
    if not self.a then self.a = true end
end

Bar = setmetatable({ base = Foo, a = false, b = false }, Foo)
Bar.__index = Bar
function Bar:CleanUp()
    self.base:CleanUp()
    if not self.b then self.b = true end
end

local bar = setmetatable({}, Bar)
bar:CleanUp()
print(bar.a)
print(bar.base.a)

CleanUp simply make boolean fields become true, and after running bar:ClearUp(), bar.a is still false, because we do self.base:CleanUp().

So how can I improve it? How can I still call the method from base class but avoid infinite recursion at the same time?

My current solution is to separate each class into standalone file, and do this:

local Super = require "Person"
-- ...

function Student:New()
    local this = Super.New(self)
    -- ...
end


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source