Igorio
Igorio

Reputation: 948

Why does clearing a passed table not work inside the function's scope?

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

Answers (2)

Martin Ender
Martin Ender

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

Lily Ballard
Lily Ballard

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

Related Questions