Search code examples
lua

table.unpack to variadic function?


Consider this test function to print arg count and type (reduction to MCVE of something else):

function printArgs(...)
    local args = table.pack(...)
    local str = args.n .. ' args:'
    for i=1,args.n do str = str..' '..type(args[i]) end
    print(str)
end

and a few basic examples:

printArgs(1, 's', nil)
-- 3 args: number string nil

printArgs(nil)
-- 1 args: nil

now I have a variable list of arguments coming from another part of my application, which I want to pass to this function, so I thought I'd use table.unpack:

printArgs(table.unpack{n=2, [1]=1, [2]='s'})
-- 2 args: number string

so far so good, but the following tests do not produce the expected results (should produce the same result as the first two tests):

printArgs(table.unpack{n=3, [1]=1, [2]='s'})
-- 2 args: number string

printArgs(table.unpack{n=1})
-- 0 args:

Why? How to fix?


Solution

  • The reason is simple, table.unpack does not recognize n, its default length is #t.

    You should use its 3rd argument to indicate the length:

    local t = {n=3, [1]=1, [2]='s'}
    printArgs(table.unpack(t, 1, t.n))
    

    And you can redefine table.unpack to make it more elegant:

    local unpack = table.unpack
    function table.unpack(t, i, j)
        return unpack(t, i, j or t.n)
    end
    printArgs(table.unpack{n=3, [1]=1, [2]='s'})