How to refer to an object without creating a new one? OOP

So i got into OOP and i want to create a player store table with metatables. When the player joins it creates the object but later on in another script i want to access the metatable without making a new one. Should i just insert the metatable into the module table or what can i do?

A metatable is just a regular table meant to be attached to other tables to provide custom behavior .
If you are creating an object of your class when a player joins your game, and want to access it from another script, you can insert the object into another table and store it there for reference.

--// Store.lua
--// Reduced example without types
local SimpleStore = ({});
SimpleStore.__index = SimpleStore; --// Whenever the object of the metatable SimpleStore is indexed [like Object.Data], it refers to itself (to prevent unexpected behavior)

function SimpleStore.new(): ()
    local self = setmetatable({
        StoredValue = nil;
    }, SimpleStore); --// Creating a new object with `SimpleStore` being the metatable.
    return (self);
end;

function SimpleStore:Store(Value: any): ()
    self.StoredValue = Value; --// example
end;

return (SimpleStore);

In another script, or a module, you can create something like this:

--// Example.server.lua
local StoredObjects = ({});

Players.OnPlayerAdded:Connect(function(Player: Player): ()
    local PlayerObject = SimpleStore.new();
    PlayerObject:Store(Player.UserId);
    StoredObjects[Player] = PlayerObject;
end);

--// somewhere later in the script, you could access the stores like this-
local SpecificStore = StoredObjects[SpecificPlayer];

--// -or loop over them
for Player, Store in pairs(StoredObjects) do
    --// do anything with Player and Store
end

If you intend to use a module to store all the player objects, just return the table at the end of the module

return (StoredObjects);

Edit 1: fixed minor typos

1 Like

Great thanks, another question ive seen the operator ; used what does it do

; is just used to mark the end of the statement/line.
It’s not necessary to use in roblox luau (just a habit from my typescript and C++ programming)

1 Like

Also do i use table.insert? Becsuse i didnt see it in your post i was confused

table.insert just pushes the value into the table. In my post I’ve done this

instead of table.insert because I want to be able to get the store using the Player instead.
If I used table.insert, it’d be hard for me to figure out which object in the StoredObjects refers to which player, unless we specify it by using another field like

self.Player = Player; --// self: SimpleStore

p.s. I’m not using types here because I don’t want you to be confused on what those do.

1 Like

Thanks for this i thought i could just insert the whole table into it. Thanks for your replies

1 Like

Forgot to mention that ; can also be used as , in tables.

1 Like

Im back again and im in studio but i cant seem to figure out how to remove it from the table.

btw instead of player stores i did queues

code:

local Queues = {}
Queues.__index = Queues

function Queues.New(Player)
	
	local Queue = {
		Owner = Player,
		MaxPlayers = 5
	}
	
	setmetatable(Queue, Queues)
	
	Queues[Player.Name.." Queue"] = Queue
	
	return Queue
end


function Queues:Remove()
	
	setmetatable(self, nil)

    Queues[self] = nil
end

function Queues:AddPlayer()
	
end

function Queues:RemovePlayer()
	
end

return Queues

–Server script:

local Queues = require(game.ServerScriptService.Queue)

local Player = game.Players:WaitForChild("Dynamite2479")

local Queue = Queues.New(Player)

print(Queues)

Queue:Remove()

print(Queues)

it prints the exact same thing even after the remove function and it gives no errors

You are setting the key (think of a key as name of the data stored in the table) of the table as Player.Name.." Queue"

But when removing the object from the queue you do Queues[self] = nil which wouldn’t work, as Player.Name.." Queue" is not equal to the queue object.
Basically when removing something from a dictionary you’d do something like this

function Queues:Remove()
	
	setmetatable(self, nil)

    Queues[self.Owner.." Queue"] = nil
end

Or instead of doing this

you could do this aswell:

--// adding to global queues
Queues[Player.Name] = Queue;

--// when removing
Queues[self.Owner.Name] = nil;

sorry for the late reply i had college lol

1 Like

Also looking at this code, you aren’t using setmetatable properly.
The logic is correct, just assign it to self and return it, because right now you are returning the table Queue and not the object returned by using setmetatable()

function Queues.New(Player)
	local Queue = {
		Owner = Player,
		MaxPlayers = 5
	}
	local self = setmetatable(Queue, Queues) --// object is now stored in `self`
	Queues[Player.Name] = self
	return self
end
1 Like

Thanks alot, sorry if i seem a lil annoying ive been trying to learn for months and couldnt even grasp OOP

No problem.
It’s totally fine, because most of us have been in this state of learning new things.
It can be difficult to understand at first, but thanks to the internet, everything gets simplified.
I’m just trying to help others with understanding concepts, about the engine and what not (mainly coz I learned things the hard way and I don’t want others to go through the same thing)
If you have any more doubts or issues regarding OOP you can contact me on discord @glaphyre

1 Like