Table changes without being set to do so

This should be in the category of engine bugs, anyway.

local totalDataOnJoin = {}
function module:dataOnJoin(information)
    --
    if information then
        if information["Option"] == "set" then
            print("setting data")
            totalDataOnJoin[information["UserId"]] = information["Data"]
        else if information["Option"] == "remove" then
                totalDataOnJoin[information["UserId"]] = nil
            end
        end
    end
    --
    print(information["Option"], totalDataOnJoin)
    return totalDataOnJoin
end

I have this function which is the only one that makes changes to the table, however, when I change my data value the table still changes without printing the print(“setting data”) I’m so confused on this behaviour

1 Like

I don’t think that there is enough context here to figure out what is going on.

3 Likes

it’s literally enough explanation, i’ve been trying to debug it for so long but nothing works

This table isn’t supposed to change at all, and if it does, the print(“setting data”) runs. But it doesn’t, and the table still changes anyway

If you don’t have the skill enough to fix it or tell me it’s an engine bug, just tell so

1 Like

I agree with VitalWinter, there is something else that we are not seeing. If the print statement “setting data” is not running, then that if block is being bypassed; therefore the line directly underneath of it is not running.

Just a guess here but it could be a problem with references. For instance:

local originalTable = {
	UserId = {1,2,44,5555}
}

local referencedTable = originalTable.UserId
referencedTable[1] = nil --Notice that I'm setting the value to nil in the referenced table

for i,v in pairs(originalTable.UserId) do --Note that I'm iterating through the originalTable
	print(i, v)
end

This will actually remove the originalTable.UserId[1] value. Whenever a variable is set to a table, then a reference to that table is used not a separate copy.

[Edit]: Changed to originalTable.UserId in the for loop to make it easier to see what happened

1 Like

Engine bug? You’re still in the phase of stacking conditional chains.

else if should be elseif.

Can you share the code responsible for the method’s call?

No, it’s just preference, and I don’t even think it’s an engine issue, but i had been for over 4 hours debugging and as @2Gethere_Games said, it’s probably a table reference issue or cloning tables issue

However i even did search on “find all” and only that function uses the table reference

I’ll continue debugging today because @2Gethere_Games is totally righr

I will mark your post as a solution, because it really should be, although yesterday I did check this by cloning the table instead, it wouldn’t work.

And the code I shared is the only function that modifies the table, other functions in my script only read the table

It’s rarely though, that it’s a reference issue because i use module.Table ={} for this, even with variables, storing in other modules, function returns, nothing has yet worked

There’s a significant difference between the two, it isn’t a preferential difference, stacking conditional chains creates additional unnecessary lexical scopes.

if true then
	--1st scope.
else
	--2nd scope.
	if false then
		--3rd scope.
	end
end

I can’t really say for certain what the problem is, but I can take a couple of guesses and toss out a bunch of info.

To create a completely new, non-referenced copy of the table, you’ll need to create a deep copy of the table if it’s multiple dimensions deep. That link is also a perfect example of recursion (a function calling itself) and can save a lot of time and headache if it’s used correctly, most importantly it’s scalable.

It’s easier to think of everything in the form of tables when dealing with modules instead of something completely new; Mainly because they are a table and so they behave exactly like one:

Module Script

local module = {
	Table = {5,4,3,2,1}
}

function module.SomeFunction()
end

function module.SomeOtherFunction()
end

return module

Script

--Iterating through a module (not sure of any use cases for this though haha)
local exampleModule = require(script.Parent)
for i,v in pairs(exampleModule) do 
	print(i, v)--Prints Table and its contents, the two functions as well as their memory location
end

I’ve created some quick examples of modules that showcase some of the traps as well as more examples of modules behaving very table-y:

Module Script

local module = {
	Table = {"a", "B"};
	PrintThisOut = function(printRequest)
		print(printRequest)
	end;
}

local someOtherTable = {5,4,3,2,1}
function module.ReturnTableReference()
	return someOtherTable
end

return module

Script

--Requiring a module gives a reference to everything located inside the module's table:
local exampleModule = require(script.Parent)
print(exampleModule.Table[1]) --prints a
exampleModule.Table[1] = nil --removing a key/value from module.Table in the other script
print(exampleModule.Table[1]) --prints nil



--Clearing the memory of a reference only affects the reference:

exampleModule = nil --ONLY removes the reference, keeps exampleModule intact
exampleModule = require(script.Parent) --reference the module again
print(exampleModule.Table[1]) --it really did remove it from earlier!



--Accessing a function in the module based off of its key:
exampleModule.PrintThisOut("Example") --prints  Example



--Returned tables are also references:
local referencedTable = exampleModule.ReturnTableReference()
referencedTable[1] = nil
referencedTable = nil --ONLY removes the reference, keeps "someOtherTable" intact
referencedTable = exampleModule.ReturnTableReference() --call the function again just to prove it's the original copy :)
for i,v in pairs(referencedTable) do
	print(v) --removed the first key which held the value 5 from the table of "someOtherTable"
end

I hope one of these solves your problem. Good luck!

1 Like