Home > Blockchain >  Table of Objects in Lua
Table of Objects in Lua

Time:11-19

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
  • Related