Why does Lua make it so hard to truly copy a variable by value and not just by reference?
Because what it means to "copy" a table depends very much on what is in that table.
First, some nomenclature. You are not referencing a "variable"; you are getting a reference to a table. A "variable" is just a holder for stuff, like a number, a string, or a reference to a table.
So when you say "truly copy a variable", what you actually mean is to "copy a table." And... that's not easy.
Consider this table:
local tbl = {x = 5, y = {20}}
If you want to copy that table, do you want to have the new table's y
field have a copy of the table that the old one stored? Or do you want that table to itself be a copy of the original?
Neither answer is wrong; which one you want depends entirely on what you want to do. But you can't go around blindly doing recursive copies of tables because:
local tbl = {x = 5, y = {20}}
tbl._tbl = tbl
This table now stores a reference to itself. Trying to do a blind recursive copy of that table will cause infinite recursion. You would have to detect that the table references itself and thus have the new table store a reference to the new table. And it gets even more complicated:
local tbl = {x = 5, y = {20}}
tbl.z = tbl.y
This table now has two fields that reference the same table. If you want to have a true copy of that table, then the copy needs to realize that two fields reference each other, so that when it copies the first field, it can have the second field reference the new copy rather than copying it again.
And I haven't even gotten into metatables and the gymnastics you can get up to with them. Nor does this include a discussion of things that are fundamentally non-copyable, like userdata objects from C-based APIs. If I store the result of io.open
in a table, there is no mechanism for copying that file handle. So what should your copy routine do?
Lua has no default table copying API in order to make sure that you will yourself take the time to figure out how complex your copying algorithm needs to be.