lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi guys,

I have found some problems using inheritance in lua when my object contains
other tables and i was wondering if there's a better way to handle it.

The best way to explain it is through an example:

--------------------------------------------------------------

local luaprint = print

-- Class Template
local Class = {
    New = function (self, obj)
        local obj = obj or {}
        setmetatable(obj, self)
        self.__index = self
        return obj
    end
}

-- Base Class
local Base = Class:New {
    name = "Base",
    v1 = 1,
    
    --------- OPTION  1 ---------
    test = { 
        v2 = -1
    },
    --------- OPTION  1 ---------

    print = function(self)
        luaprint("name = " .. self.name .. ", v1 = " .. self.v1)
    end
}

function Base.test.print()
    luaprint("Class Base")  
end

function Base.test.print_v(self)
    luaprint("v2 = " .. self.v2)  
end

-- First Class

local A = Base:New {
    name = "A",
    v1 = 2,
}

A.test.v2 = -2

function A.test.print()
    luaprint("Class A")
end

-- Second Class

local B = Base:New {
    name = "B",
    v1 = 3,
}

B.test.v2 = -3

function B.test.print()
    luaprint("Class B")  
end

-- prints
Base:print()
Base.test.print()
Base.test:print_v()

A:print()
A.test.print()
A.test:print_v()

B:print()
B.test.print()
B.test:print_v()
--------------------------------------------------------------


Now the above code gives this output

--------- OUTPUT 1 ---------
name = Base, v1 = 1
Class B
v2 = -3
name = A, v1 = 2
Class B
v2 = -3
name = B, v1 = 3
Class B
v2 = -3
--------- OUTPUT 1 ---------

as you can see when B changes an element in the subtable "test" that value
will change for ALL instances.

A Fix for this is redefining the Base like this:

--------------------------------------------------------------

-- Base Class
local Base = Class:New {
    name = "Base",
    v1 = 1,
    
    --------- OPTION  2 ---------
    test = Class:New {
        v2 = -1
    },
    New = function(self, obj)
        local obj = Class.New(self, obj)
        obj.test = self.test:New{}
        return obj
    end,
    --------- OPTION  2 ---------

    print = function(self)
        luaprint("name = " .. self.name .. ", v = " .. self.v)  
    end
}
--------------------------------------------------------------


which then gives the expected output


--------- OUTPUT 2 ---------
name = Base, v1 = 1
Class Base
v2 = -1
name = A, v1 = 2
Class A
v2 = -2
name = B, v1 = 3
Class B
v2 = -3
--------- OUTPUT 2 ---------


I believe this happens because all tables are referenced whilst other types
are actually copied but i was wondering if there's any way to automate the
process / handle this in a better way as it's something that seems really
prone to errors that are hard to track down.

Thank you



--
View this message in context: http://lua.2524044.n2.nabble.com/inheritance-and-sub-tables-tp7656847.html
Sent from the Lua-l mailing list archive at Nabble.com.