Reputation: 948
Clearing a table like so causes expected behavior:
table1 = { "a" }
table1 = {}
print(unpack(table1)) -- results in printing a blank line
But if you do the same thing inside a function, it doesn't take:
table1 = { "a" }
function cleartest (x)
x = {}
print(unpack(x))
end
cleartest(table1) -- results in printing a blank line
print(unpack(table1)) -- results in "a"
What causes this behavior?
Edit: To clarify how passing tables in Lua works. x is not a local "copy" of table1, since it is a "value is reference" type, it is actually a reference to the actual table. For example:
table1 = { "a" }
function xisref (x)
x[2] = "b"
end
xisref(table1)
print(unpack(table1)) -- results in printing "a b" thus x is a reference to the actual table
Upvotes: 2
Views: 178
Reputation: 44289
Because you cannot actually clear the value of a table - only a name.
If you do
table1 = { "a" }
table1 = {}
You don't set { "a" }
to {}
, but you set table1
to {}
replacing the previous value. That value is now inaccessible and will eventually be cleared by the garbage collector.
When you call cleartest
, then x
will also point to the same value { "a" }
as table1
, but x
is a different (local) name for it. By doing x = {}
you simply make x
point to a new and empty table, but that changes nothing about table1
which still points to { "a" }
.
Responding to your edit:
Yes x
is a reference to the same value as table1
. But x
is still just a local name that happens to point to that value. The moment you assign something to x
, the local variable x
points to something new, without affecting the value it had previously pointed to.
Try this (anywhere, globally, locally, doesn't matter):
test1 = { "a" }
test2 = test1
-- printing them now gives the same table
test1 = 5
-- printing test1 gives 5; printing test2 still gives the table
Assigning something new to test2
and printing test1
would yield the same result.
Upvotes: 3
Reputation: 185861
You're not clearing the table. You're creating a new table and assigning it to the variable.
In the first case, you're overwriting the table1
variable, so the later reference gets your new empty table.
In the second case, you're overwriting the x
variable, which is local to the function, so the later reference to table1
is unaffected. Note that if you had said table1 = {}
in your cleartest()
function it would have behaved like the first case.
If you truly want to clear the existing table, such that other references to the same table see the cleared state, you need to write something like
for k in pairs(x) do
rawset(x, k, nil)
end
Upvotes: 1