Log In  

a = {x=10, y=25}

b = a

b.x = 99

print(a.x)

This prints 99 but I assumed it would print 10.
I wrote code with a start table. Then I set a position table equal to the start table. I was hoping to update the position table but reset the position back to the start point at any time I wanted. I tested this out in php to make sure I wasn't crazy and it worked like I expected. I tried it out in strict Lua but it gave the result above. Why does Lua change the a table when I only changed the b? How do I deal with this?

P#147872 2024-05-03 23:49

1

In Lua (and, off the top of my head, in JavaScript, and C#), simple types (number, string) are passed by value (i.e. values are copied from variable A into variable B), but complex types (table) are passed by reference (i.e. A and B are set to refer/point to the same table in program's memory). I can explain further if needed.

To make an actual copy of a table, try something like this:

for k,v in pairs(table1) do
  table2[k]=v
end
P#147873 2024-05-04 00:31 ( Edited 2024-05-04 00:33)

thanks, yaky. I found this page https://www.lua.org/pil/2.5.html
explaining that "A table is always anonymous. There is no fixed relationship between a variable that holds a table and the table itself"

thanks for the workaround.

P#147875 2024-05-04 00:37
1

@yaky Note that this will only perform a shallow copy, so tables within tables will still be passed by reference. You'd want something recursive to do a deep copy.

P#147876 2024-05-04 00:37

@Soupster
yeah.. I'm finding this out now...

start = {}
start.first = {x=10, y=25}

position = {}
for k,v in pairs(start) do
  position[k] = v
end

position.first.x = 99

print(start.first.x)
print(position.first.x)

--output:
--99
--99

was hoping for it to only change the position table, but it changes the start table as well. It did work for a single dimensional table, but I guess I'll need a for loop inside of a for loop. Seems kinda ugly.

i'm seeing this is a common problem and found this:
http://lua-users.org/wiki/CopyTable
but it all seems like a major confusion for something I normally took for granted.

P#147878 2024-05-04 02:10 ( Edited 2024-05-04 02:51)

What @Soupster said, using a function that recursively calls itself when it encounters a table is not a bad place to solve the issue. When looping through a table, you can check a variable's type using the type() function. It will return "table" if it sees that it is a table.

P#147879 2024-05-04 02:51
2
--returns a copy of table t
function tcopy(t)
 local new={}
 for k,v in pairs(t) do
  if type(v)=="table" then
   new[k]=tcopy(v)
  else
   new[k]=v
  end
 end
 return new
end
P#147881 2024-05-04 02:58
1

Thank you guys a million for the help. kozm0naut's simple and clear code works like a charm and I think I get it. Couldn't find anything that straightforward anywhere else.
just for completeness and because I'll probably look at this again in the future:

function tcopy(t)
 local new={}
 for k,v in pairs(t) do
  if type(v)=="table" then
   new[k]=tcopy(v)
  else
   new[k]=v
  end
 end
 return new
end

start      = {x=10, y=25}
position   = tcopy(start)
position.x = 99

print(start.x)
print(position.x)
--10
--99

--now revert position back to start:
position = tcopy(start)
print(start.x)
print(position.x)
--10
--10
P#147887 2024-05-04 04:02

[Please log in to post a comment]