Correctly Iterate Variadic Parameters in Lua
Our logger functionality exposes a simple interface, which doesn’t limit the number of items you can send it.
function M.info(...)
function M.error(...)
-- etc.
To send it to the syslog service, we need to convert all the items into a single string
. Normally, you would convert the variadic parameter (...)
to an array and use ipairs
to iterate over it:
local texts = {}
for index, item in ipairs({...}) do
texts[#texts + 1] = tostring(item)
end
local result = table.concat(texts, " ")
However, ipairs
has a quirk : a nil
value will cause it to stop the iteration over the array.
logger.info("foo", nil, "bar")
-- logs "foo"
How to fix this? Using select
!
select("#", ...)
retrieves the actual number of items hidden in the variadic parameter.select(i, ...)
will retrieve the item in indexi
(remember they start at 1 in Lua) from the variadic parameter.
For example -
local reduce_to_string = function(...)
local texts = {}
for index = 1, select('#', ...) do
texts[#texts + 1] = tostring(select(index, ...))
end
return table.concat(texts, " ")
end
Comments