Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do you duplicate a variable's value without using the same memory address?

I thought I understood how a variable worked with a variable being assigned an address in memory where you can store a value, though evidently I don't. I have this small snippet of code here that finds certain combination of numbers that fit into a bigger number. My issue is where if result == 0 then I try to copy the value of priorPath to a different variable completedPath, then add list[i] into the table completedPath, and then store completedPath into another table storing all possible paths. My issue is that any changes to completedPath all show up on priorPath which I don't want to happen. So back to the original question, how do I declare a variable of equal value using a different memory address?

local function testNumber(number, exit)

    if number > exit then return false end

	return exit - number

end

  

local function getPaths(list, goal, priorPath, paths)

    --print(goal)
    
    for i = 1, #list do
    
	    local result = testNumber(list[i], goal)
    
	    if result == 0 then
    
		    local completedPath = priorPath
    
		    table.insert(completedPath, list[i])
    
		    table.insert(paths, completedPath)
    
	    elseif result then
    
		    table.insert(priorPath, list[i])
    
		    paths = getPaths(list, goal - list[i], priorPath,	paths)
    
		   end
    
    end

    return paths

end

Edit: I ended up having to do something stupid like the following, and it worked, any better solutions?

local function testNumber(number, exit)


	if number > exit then return false end

		return exit - number

	end



local function getPaths(list, goal, priorPath, paths)
for i = 1, #list do

	print(list[i])

	local result = testNumber(list[i], goal)

	if result == 0 then

		local newTbl = {}

		for k,l in pairs(priorPath) do

			table.insert(newTbl, l)

		end

		table.insert(newTbl, list[i].." ")

		table.insert(paths, newTbl)

	elseif result then

		local newTbl = {}

		for k,l in pairs(priorPath) do

			table.insert(newTbl, l)

		end

		table.insert(newTbl, list[i])

		paths = getPaths(list, goal - list[i], newTbl, paths)

	end

end

return paths

end

1 answer

✓ Accepted answer

This happens because userdata and table data types are pass-by-reference, while numbers, strings and other data types are pass-by-value. This means that, as you have found, creating new variables will still refer to the same copy of the table. To solve this, there are two options that I know of:

In the case of predetermined tables (for example, a table containing default stats), you can create and return the table from a function to obtain a unique copy of the table every time. For example:

local function GetStats()
	return {
		Money = 5;
		Level = 0
	}
end
local Stats1 = GetStats()
local Stats2 = GetStats()
print(Stats1 == Stats2) --> false

Alternatively, if your table is created/altered while the game is running (in most cases), you can make a function to create a unique copy of the table:

local function DeepCopy(Table)
    local Copy = {}
    for Key, Value in pairs(Table) do
	    if type(Value) == "table" then
		    Copy[Key] = DeepCopy(Value)
		else
			Copy[Key] = Value
		end
	end
	return Copy
end
local Table1 = {"a", "b", "c"}
local Table2 = DeepCopy(Table1)
print(Table1 == Table2) --> false

Hope this helps!

1 comment

0

I would assume this behavior varies from language to language? Such that in Java something like an ArrayList might not be a pass-by-reference?

This discussion is preserved as it was. New answers, comments, and votes are closed.