Search code examples
lualua-tableunpack

Lua can't unpack a table starts with two nil assigned elementwise


I tried the following code in Lua. The first four cases work well but the last two fail. I get nil as results in those two. What is the problem?

v = {nil, 10, nil}
a, b, c = unpack(v)
-- Output: a, b, c =  nil 10  nil
print('a, b, c = ', a, b, c)

v = {nil, nil, 10}
a, b, c = unpack(v)
-- Output: a, b, c =  nil nil 10
print('a, b, c = ', a, b, c)

v = {}
v[2] = 10
a, b, c = unpack(v)
-- Output: a, b, c =  nil 10  nil 
print('a, b, c = ', a, b, c)

v = {}
v[1] = nil
v[2] = 10
v[3] = nil
a, b, c = unpack(v)
-- Output: a, b, c =  nil 10  nil
print('a, b, c = ', a, b, c)

v = {}
v[3] = 10
a, b, c = unpack(v)
-- Output: a, b, c =  nil nil nil
print('a, b, c = ', a, b, c)

v = {}
v[1] = nil
v[2] = nil
v[3] = 10
a, b, c = unpack(v)
-- Output: a, b, c =  nil nil nil
print('a, b, c = ', a, b, c)

Solution

  • When using a table as an array, all elements are required to have values different than nil.

    Setting the value for a key to nil effectively removes that key from the table. But in an array all integer keys from 1 to the length of that array must be set. “Holes” are not allowed. So the behaviour in all your cases is unspecified.

    You can verify by printing all key/value pairs in the table:

    t = {0, nil, 2, 3}
    
    print("pairs:")
    for k, v in pairs(t) do
        print("["..k.."]", v)
    end
    

    And note how ipairs breaks, since it stops at the first nil element.

    print("ipairs:")
    for k, v in ipairs(t) do
        print("["..k.."]", v)
    end
    

    Workaround in your case is described in an answer here: Lua unpack bug?