Why overwriting an object argument does not pass the new reference to outside scope?

Viewed 35

I'm a bit confused with how Lua treats object references in function arguments. Consider this example:

local tableA = {name = "A"}
local tableB = {name = "B"}
local tableC = {name = "C"}

local function childA(a, b)
    a = tableC
    b.name = "This works"
end

local function childB(a, b)
    print("a =", a.name) -- expected to print "C"
    print("b =", b.name) -- prints "This works" as expected
end

local function parentFunction(a, b)
    childA(a, b)
    childB(a, b)
end

parentFunction(tableA, tableB)

I would expect that in the childA function the a parameter will be replaced by reference to tableC that will continue to be tableC from now on, but it does not happen. Whereas if I change just a property of such parameter in the b parameter it will affect reads of the object down the line. Why the overwrite is not working like this?

1 Answers

Table values are copied by reference, not by value.

in childA you assign tableC to a. a is local to childA.

a = tableC just adds a second reference to the table tableC refers to. This has no effect on the actual table nor any other reference to it.

Once childA has returned, a is out of scope so the reference you just added is removed.

Make sure you understand that in local tableA = {name = "A"} you create a table value with the table construtor {} and a local reference tableA to that table value. local a = tableA just creates another reference to that table, not a second table! Then a = tableC re-refers a to the table created here local tableC = {name = "C"}

You basically write another address on a piece of paper. That doesn't affect the house at the original address.

Related