Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Function does not update variable?

Asked by 7 years ago

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

Log in to vote
3
Answered by
BlackJPI 2658 Snack Break Moderation Voter Community Moderator
7 years ago
Edited 7 years ago

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)
0
Thank you for clarifying! DepressionSensei 315 — 7y
0
No problem! BlackJPI 2658 — 7y
Ad
Log in to vote
1
Answered by 7 years ago

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.

Answer this question