Having Trouble with OOP Implementation

Code Reference

Module Script (OOP Class)
The Constructor:

function ItemGrid:new(LengthX,LengthY,Name)
    self.Class = "ItemGrid"
    self.Name = Name or nil
    self.Width = LengthX
    self.Height = LengthY
    self.SelectedItem = nil
    local gridObject = table.create(LengthX)
    for x = 1, LengthX do
        gridObject[x] = table.create(LengthY)
        for y = 1, LengthY do
            gridObject[x][y] = nil
        end
    end
    self.Table = gridObject
    return self
end

Server Script
The Dictionary:

local inventoryDictionary = {}

The constructor call:

function NewGrid(sx,sy,Name)
    local ig = ItemGrid:new(sx,sy)
    ig.Name = Name
    print("Adding item grid to index",Name)
    inventoryDictionary[Name] = ig
    ig:Print()
    return ig
end
local pbp = NewGrid(5,6,"Player Backpack")
local pbp2 = NewGrid(12,8,"Player Backpack 2")

The Problem
When I call a class method to print pbp and again to print pbp2, it prints the exact same thing both times, which it should not do.

Notes/Observations

  • Printing pbp before local pbp2 = NewGrid(12,8,"Player Backpack 2") prints correctly.
  • Implementing the print method into the constructor prints them correctly (but not in the server script where I need it)
  • Printing them as I stated in my problem prints two of pbp2, and none of pbp
  • Initializing the ItemGrid object/constructing it outside of a function as detailed the following snippet also DOES NOT work and results in the same results.
local grid1 = ItemGrid:new(4,4)
local grid2 = ItemGrid:new(6,6)
grid1:Print()
grid2:Print()

Any help or pointers would be immensely appreciated :heart:

Please drop a message to my discord if you reply (If you want :stuck_out_tongue: ) @apd435#2477

I believe ItemGrid is the module script itself,

local ItemGrid = {}

function ItemGrid:new()
end

return ItemGrid

Your constructor isn’t constructing a new object since self refers to ItemGrid when you call :new()

Proper implementation:

local ItemGrid = {}
ItemGrid.__index = ItemGrid

function ItemGrid.new(instance) -- I like to hook the object to an instance so you can reference it from other scripts later
local self = {}
setmetatable(self, ItemGrid)
-- Object behavior
--
ItemGrid[instance] = self
return self
end

function ItemGrid:anyHeight()
self.Height = math.random(1, 30) -- self here refers to self from ItemGrid.new(), assuming you call it from the table returned by ItemGrid.new()
end

local pbp = ItemGrid.new()
pbp:anyHeight()

OR you can avoid metatables if you like

local ItemGrid = {}

function ItemGrid.new(instance) -- I like to hook the object to an instance so you can reference it from other scripts later
    local self = {}
    -- Object behavior
    print("itemgrid created")
    --
    function self:anyHeight()
    self.Height = math.random(1, 30) -- self here refers to self from ItemGrid.new(),assuming you call it from the table returned by ItemGrid.new()
    end

    ItemGrid[instance] = self
    return self
end


local pbp = ItemGrid.new()
pbp:anyHeight()
1 Like

Thanks a bunch! Yeah, the issue was that I wasn’t doing setmetatable as I shortly discovered upon inspecting my code right after this post.

1 Like