This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
MrObsidy's profile picture

Are tables passed by reference or by value?

Started by MrObsidy, 24 April 2019 - 05:17 PM
MrObsidy #1
Posted 24 April 2019 - 07:17 PM
Kind of a strange question.
I want to know if I can pass a table as a parameter of an API function and have it modified there or if I have to utilize return values:

Will

local table = {
  [1] = "foo"
}

api.makeBar(table)

print(table[1])

with api.makeBar(param) being

function makeBar(param)
  param[1] = "bar"
end

print "foo" or "bar" as the result?

EDIT: By testing, I found out that Lua indeed is pass-by-reference (the above code outputs "bar".)

Is this consistent or undefined behaviour?
Edited on 24 April 2019 - 05:21 PM
Luca_S #2
Posted 24 April 2019 - 07:41 PM
Tables in Lua are neither values nor variables; they are objects. If you are familiar with arrays in Java or Scheme, then you have a fair idea of what we mean. However, if your idea of an array comes from C or Pascal, you have to open your mind a bit. You may think of a table as a dynamically allocated object; your program only manipulates references (or pointers) to them.
Source

It is a bit like passing an object as a parameter in Java. I think there was even some special name for that kind of parameter passing, but I can't find that right now.

It is call by value, however your value is a reference.
You can see the difference if you make a clearTable() function:

local function clearTable1(t)
  t = {} -- This won't work, with true call by reference it would'
end
local function clearTable2(t)
  for k, _ in pairs(t) do
	t[k] = nil -- This works
  end
end
Edited on 24 April 2019 - 05:42 PM
MrObsidy #3
Posted 24 April 2019 - 07:56 PM
Thank you very much,
Bomb Bloke #4
Posted 26 April 2019 - 09:25 AM
EDIT: By testing, I found out that Lua indeed is pass-by-reference (the above code outputs "bar".)

Just to make sure you're clear on this, Lua always passes values.

When you attempt to assign a table (or function, or coroutine…) to a variable, you actually end up assigning a pointer to it instead - which you can see if you try printing the variable's contents. Copying such values means that you then have multiple pointers leading to the one memory object: you can't actually pass copies of tables themselves because you never actually assign tables in the first place.