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

Function does not update variable?

Hi!

I have a function that takes two arguments, a StringValue object and a variable that is set to update with my desired result. My issue is with the updating of the second argument.

I've used print() to determine that I'm indexing the correct value and yet I still can't get the result I've want, so I've deduced that either this is impossible or I'm making a major mistake.

Here is my code:

local uis = game:GetService("UserInputService")
local players = game:GetService("Players")
local player = players.LocalPlayer

local stances = {
	["Water"] = {
		[1] = {5, ""},
		[2] = {10, ""},
		[3]	= {15, ""},
		[4] = {20, ""},
		[5] = {35, ""}
	} ,
	
	["Earth"] = {
		[1] = {5, ""},
		[2] = {10, ""},
		[3]	= {15, ""},
		[4] = {20, ""},
		[5] = {35, ""}
	} ,
	
	["Fire"] = {
		[1] = {5, ""},
		[2] = {10, ""},
		[3]	= {15, ""},
		[4] = {20, ""},
		[5] = {35, ""}
	} ,
	
	["Air"] = {
		[1] = {5, ""},
		[2] = {10, ""},
		[3]	= {15, ""},
		[4] = {20, ""},
		[5] = {35, ""}
	} ,	
}

local key = "T"

function setStance(Element, Stance)
	if stances[Element] then	
		local rng = math.random(1, 5)
		
		if stances[Element][rng][1] then
			Stance = stances[Element][rng][1]	
			return true
		else
			return false	
		end	
	else
		return false	
	end
end

uis.InputBegan:connect(function(input, gameProcessedEvent)
	if input.KeyCode.Name == key and not gameProcessedEvent then
		local plrElement = player:FindFirstChild("Element").Value --I've set this value to Fire, this isn't the issue. I've already used print() to figure out that it isn't an issue with my values
		local stance
		if setStance(plrElement, stance) then
			print(stance)
		else
			print("Error")	
		end
	end	
end)

To clarify more, declaring a variable with no value will set the variable's value to nil, and upon printing stance after confirming that it has updated in the function, I get nil.

This is really stumping me. If I could get a reason why this is happening it'd be very appreciated. Thanks!

2 answers

✓ Accepted answer

Your Problem

local stance
setStance(plrElement, stance)

What you are trying to do is set the variable stance by passing it into this function. This is fine and dandy and will work as you expect when the variable is passed in by reference, but not when it is passed by value.


"Passing by Reference" vs "Passing by Value"

When you pass in an argument by reference, the parameter of the function then points to the same memory address as the argument you passed in. This means that when you make changes to the parameter inside the function, you also make changes to the variable outside the function.

However, when you pass in a variable by value it copies the data from your variable and assigns it to the parameter, giving it a different memory address. When you make changes to the parameter inside the function, the changes are not made to your variable you passed i in as it points to a different set of memory.

In Lua, we can not control how our variables work. There are default ways that each type of object act when you pass them into functions:

By Reference: tables, functions, threads, and userdata values

By Value: nil, boolean, number, string


Solution

Since your variable is nil, we are going to need to change the way that you function works. We need to return back the stance we want and to assign to the variable:

function setStance(Element)
	if stances[Element] then
		local rng = math.random(1, 5)

		if stances[Element][rng][1] then
			return stances[Element][rng][1]
		else
			return nil
		end
	else
		return nil
	end
end

uis.InputBegan:connect(function(input, gameProcessedEvent)
	if input.KeyCode.Name == key and not gameProcessedEvent then
		local plrElement = player:FindFirstChild("Element").Value
		local stance = setStance(plrElement)

		if stance then
			print(stance)
		else
			print("Error")  
		end
	end 
end)

2 comments

0

Thank you for clarifying!

0

No problem!

You're passing it by value, and not by reference. Passing by value, you're just making a copy and not really changing it, which means the original variable wasn't modified.

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