2

So I have a for loop:

for k, pt in pairs(points) do
    self.centers[k] = Center:new() --<centers> is part of my Map object, and Center is an object
    local bottomleft = Corner:new()
    table.insert(self.centers[k].corners, bottomleft)
    ...--repeats 4 times for each corner of a square
end

There are 256 point in the list (points) and when I try to check how many values each center object has in the list (centers) it comes out as:

print(#self.centers[1].corners) --> 1024

I don't know why there are 4 times as many values in each of the (center.corners) lists when there should only be 4.

How do I fix this?

Edit:

function Center:new (o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

That is the Center:new() method

  • Can we see the points table and/or the new method of center? – warspyking Apr 04 '17 at 01:42
  • 1
    I ask this because if Center:new is returning the same object this is easily explainable. – warspyking Apr 04 '17 at 01:44
  • function Center:new (o) o = o or {} setmetatable(o, self) self.__index = self return o end – Taner Seytgaziyev Apr 04 '17 at 02:03
  • Did you create `Center.corners` table per object? I don't see it in `Center` constructor. It's either shared across many `Center` objects, or your code should fail on `table.insert(self.centers[k].corners, ..)` with runtime error. See the sample at http://ideone.com/Fbvt4S. Another possible issue is if your `points` is not indexed by consecutive integer indices, so checking first center with `self.centers[1]` might be incorrect, as pairs() can return key that is not a number, but whatever is there in `points` table. – Vlad Apr 04 '17 at 07:05
  • Also, quick note on efficiency, you're setting self.__index every time you create a center object. You should set that beforehand, so you don't have to stick it in the constructor – warspyking Apr 04 '17 at 14:21

1 Answers1

1

When you create a new Center object you set

.__index = self

So later when you index

self.centers[k].corners

in this line

table.insert(self.centers[k].corners, bottomleft)

it returns the self object, causing your corners to be inserted into what I assume is Center

Seeing as you are adding 4 corners to this same table 256 times, it isn't adding 1024 corners to each table, it's adding them to one single table, one you are indexing and you don't even realize.

Your solution is simple, simply add the corners property to each center:

function Center:new (o)
    o = o or {corners={}}
    setmetatable(o, self)
    self.__index = self
    return o
end

This works because __index only fires if an index doesn't exist in a table already. This stops redirecting.

P.S.: Thanks for providing the Center:new() code, this answer wouldn't be possible without it!

warspyking
  • 3,045
  • 4
  • 20
  • 37