Programming in Lua : 5.2 states the following around using variadic arguments in functions:
Sometimes, a function with a variable number of arguments needs to pass them all to another function. All it has to do is to call the other function using unpack(arg) as argument: unpack will return all values in arg, which will be passed to the other function…
Assigning a variable to the output of unpack(...)
rather than using the result of the method itself does not necessarily guarantee that the variable is equal to the return values created by unpack(...)
. Recall that the unpack(...)
function behaves like so:
function unpack(list)
-- i = 1, j = #list
return list[i], list[i+1], ..., list[j]
end
There is a subtle difference between passing the results of unpack(...)
to a function and passing a variable assigned to whatever unpack(...)
returns to a function, illustrated below:
function powers()
return {1, 2, 4, 8, 16, 32, 64}
end
local first, second, third = table.unpack(powers())
print(first, second, third)
-- 1, 2, 4
print(table.unpack(powers()))
-- 1, 2, 4, 8, 16, 32, 64
As you can see, assigning n
variables to the result of unpack(...)
will assign the first n
values of unpack(...)
to those first n
variables. If you just assign one value to a call to unpack(...)
, it’s only going to take on the first value in that list passed to unpack(...)
. This is why the Lua documentation tells you to just straight up use unpack(...)
in the passed arguments of whatever function is accepting it.
A more closely aligned example to your code demonstrating this is below:
function foo(func, ...)
unpacked = table.unpack(...)
func(unpacked)
end
function bar(func, ...)
func(table.unpack(...))
end
foo(print, {"Goodbye", "cruel", "world."})
bar(print, {"Goodbye", "cruel", "world."})
The call to foo
only returns "Goodbye"
whereas the call to bar
returns the entire string, as expected. See this in effect here. I’m sure you want the second, so just use unpack({...})
instead of the unneccesary params
assignment.
This is my guess as to why the code is underlined. I could be entirely off the mark, though…