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]