I'm attempting to create a Lua object like this
Block = {x = 0, y = 0, color = "red"}
function Block:new (x, y, color)
block = {}
setmetatable(block, self)
self.__index = self
self.x = x
self.y = y
self.color = color
return block
end
Then putting several instances of this object into a table in a separate file
blocks = {}
table.insert(blocks, Block:new(0, 0, 'red'))
table.insert(blocks, Block:new(2, 0, 'blue'))
table.insert(blocks, Block:new(1, 1, 'green'))
for i,v in ipairs(blocks) do
print(i,v.x, v.y, v.color)
end
But my output is
1 1 1 green
2 1 1 green
3 1 1 green
How can I get these objects to retain their own instance in the table?
CodePudding user response:
In your code
Block = {x = 0, y = 0, color = "red"}
function Block:new (x, y, color)
block = {}
setmetatable(block, self)
self.__index = self
self.x = x
self.y = y
self.color = color
return block
end
The first problem that causes all your instances to be the same is that you did not make block
local to the function. Instead each call to Block.new
operates on the same global variable. So every time you call it you overwrite the result of the previous call.
The second problem is that you do not modify your instance but the class itself. As your instances don't have x
, y
and color
you fall back to Block's value due to __index referring to Block
self refers to the table Block
as function Block:new(x, y, color)
is equivalent to function Block.new(self, x, y, color)
and your function call Block:new(0, 0, 'red')
is equivalent to Block.new(Block, 0, 0, 'red')
So you try to create an instance of the Block
class named block
. If you want to change that instances properties you must use block.x = x
instead of self.x = x
as you otherwise will alter Block
which then would reflect on all instances.
Block = {x = 0, y = 0, color = "red"}
function Block:new (x, y, color)
local block = {}
setmetatable(block, self)
self.__index = self
block.x = x
block.y = y
block.color = color
return block
end
CodePudding user response:
You should be setting x,y,color on block
rather then self
function Block:new (x, y, color)
block = {}
setmetatable(block, {__index = self})
block.x = x
block.y = y
block.color = color
return block
end