OOP defaults table values defined after calling constructor again?

When I reset my player and I have table values in my module.defaults which servers as a class default value holder for every class that gets constructed… the table values in there stay when the Localscript is replicated to the client again after dying… Why?

local module = {}

module.defaults = {
	tbl = {},
	tbl2 = {},
}

module.metatable = {__index = module.defaults}

function module:Init()
	-- If I were to print module.defaults here, It will actually show the previous class table values...
	local obj = {}
	setmetatable(obj, module.metatable)
	return obj
end

function module:addTableValueTest()
	table.insert(self.tbl2, "test")
end

This is how I’d call it:

local rs = game:GetService("ReplicatedStorage")
local module = require(rs:FindFirstChild("Module"))

-- Instantiate class.
main = module.Init()

-- Add value "test".
module.addTableValueTest(main)

So let me repeat / rephrase my question.
When I print the values in the constructor phase after my player has reset… why do the table values from the previous class remain there? They shouldn’t remain there right since the defaults are inherited to every class…? Is this because I’m constructing the same “main” class twice? But why does the class not get re-defined? All the other values in the defaults seem to not remain, like normal variable values.

What am I misunderstanding here.

Tables and userdatas are passed by reference. Every other type is passed by value.

If you want tbl and tbl2 to be unique for every instance of your object then you need to declare them in the constructor.

Otherwise when you index them through the metatable every different instance will be accessing the same table.

function module:Init()
	-- If I were to print module.defaults here, It will actually show the previous class table values...
	local obj = {
		tbl = {},
		tbl2 = {}
	}
	setmetatable(obj, module.metatable)
	return obj
end
1 Like

Ohhhh that makes sense! Thank you so much for clarifying this. :smile: