Function/variable scope (pass by value or reference?)

frooyo picture frooyo · May 25, 2011 · Viewed 43.8k times · Source

I'm completely confused by Lua's variable scoping and function argument passing (value or reference).

See the code below:

local a = 9        -- since it's define local, should not have func scope
local t = {4,6}    -- since it's define local, should not have func scope

function moda(a)
  a = 10           -- creates a global var?
end
function modt(t)
  t[1] = 7         -- create a global var?
  t[2] = 8
end

moda(a)
modt(t)
print(a)  -- print 9 (function does not modify the parent variable)
print(t[1]..t[2])  -- print 78 (some how modt is modifying the parent t var) 

As such, this behavior completely confuses me.

  • Does this mean that table variables are passed to the function by reference and not value?

  • How is the global variable creation conflicting with the already define local variable?

    • Why is modt able to modify the table yet moda is not able to modify the a variable?

Answer

Bas Bossink picture Bas Bossink · May 25, 2011

You guessed right, table variables are passed by reference. Citing Lua 5.1 Reference Manual:

There are eight basic types in Lua: nil, boolean, number, string, function, userdata, thread, and table. ....

Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.

So nil, booleans, numbers and strings are passed by value. This exactly explains the behavior you observe.