I’m writing a lua script, and one of the things it does is copy a table into a table of tables, and apply a couple transformations to it. What’s odd though is when i go to use one of those tables later (and modify some of it’s properties), changes will also seem to show up in other tables! Code:
-- thanks to http://stackoverflow.com/questions/1283388/lua-merge-tables/1283608#1283608
-- tableMerge:
-- merges two tables, with the data in table 2 overwriting the data in table 1
function tableMerge(t1, t2)
for k,v in pairs(t2) do
if type(v) == "table" then
if type(t1[k] or false) == "table" then
tableMerge(t1[k] or {}, t2[k] or {})
else
t1[k] = v
end
else
t1[k] = v
end
end
return t1
end
--tableCopy:
--takes a table and returns a complete copy including subtables.
function tableCopy(t)
return tableMerge({}, t)
end
local t1 = { a = 1, b = true, c = "d", e = { f = 2 } }
local t2 = tableCopy(t1)
t2.b = false
t2.e.f = 1
print(t1.b) -- prints true as it should
print(t1.e.f) -- prints 1!
[removed other code for reasons of the information it contains, and this a good reproduction of the bug]
so is it a bug in my code or something? i can’t figure it out….
This is how Lua tables work – they don’t get copied around, only references to the tables are passed to functions or stored in tables instead. If you are familiar with .NET terminology, you could say that tables are “reference types”. Observe:
This prints “world” because the modtable function gets a reference to the table and not a copy. The same thing happens when you try to store table in another table
This will print
because t and bigT.innerTable are essentially the same table.
If you want copies of the tables that you can modify independently from one-another you can write a small function to duplicate a table
This will print “no!” and “world” – t and bigT.innerTable are different tables now.