←  Ask a Pro

ComputerCraft | Programmable Computers for Minecraft

»

Are tables passed by reference or by value?

MrObsidy's Photo MrObsidy 24 Apr 2019

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 by MrObsidy, 24 April 2019 - 06:21 PM.
Quote

Luca_S's Photo Luca_S 24 Apr 2019

Quote

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 by Luca_S, 24 April 2019 - 06:42 PM.
Quote

MrObsidy's Photo MrObsidy 24 Apr 2019

Thank you very much,
Quote

Bomb Bloke's Photo Bomb Bloke 26 Apr 2019

View PostMrObsidy, on 24 April 2019 - 06:17 PM, said:

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.
Quote