Clone object in LUA

Viewed 400

I have the next code and I'm trying to create a copy of the object Test:

local Test = {} do
    local var1, var2 = {}

    function Test:Init(val1, val2, val3)
        var1.val1 = val1
        var1.val2 = val2
        var1.val3 = val3
    end

    function Test:Print()
        print(var1.val1)
        print(var1.val2)
        print(var1.val3)
    end

    function Test:New(obj)
        obj = obj or {}
        setmetatable(obj, self)
        self.__index = self
        return obj
    end
end

Then I'm creating my objects like this:

local obj1 = Test:New()
obj1:Init('a','b','c')
local obj2 = Test:New()
obj2:Init('c','d','e')

obj1:Print()
obj2:Print()

The result will be this:

c, d, e
c, d, e

As you can see the method New is not cloning correctly the object and is sharing the same instance. What am I doing wrong? I haven't cloned an object before and I'm having issues to understand how to do it. I got that code from here: https://www.lua.org/pil/16.2.html

Thanks.

1 Answers

The problem occurs because you are just changing local variables, not the object itself.

When you do local Test = {} do you are not doing too much about the Test object, you are just creating the table and then creating a new scope which will be executed immediately, and inside this scope you have the variable var1, which will be shared through the scope, not the object.

The correct way to implement variables for each is actually creating fields on it:

local Test = {} do    
    function Test:Init(val1, val2, val3)
        self.val1 = val1
        self.val2 = val2
        self.val3 = val3
    end

    function Test:Print()
        print(self.val1)
        print(self.val2)
        print(self.val3)
    end

    function Test:New(obj)
        obj = obj or {}
        setmetatable(obj, self)
        self.__index = self
        return obj
    end
end

Anyway setmetatable it's not about cloning objects, it implement shared behaviors and then you can create as many objects you want with those behaviors.

Related