jawo
jawo

Reputation: 896

Number of returned values

I've got a function which is returning a bunch of values and I can't know how many arguments are returned.

function ascii( value )
[...]
    if type( value ) == "string" then
      if #value > 1 then
        local temp = {}
        for i = 1, #value do
          table.insert( temp , (value:byte(i)) )
        end
        return unpack( temp ) --<-- unknown number of return values
      else
        return value:byte(1)
      end
    end
[...]
end

How can I know how many values are returned?

My first idea was this:

return numberOfValues, unpack( temp )

But in most cases, the number of values is irrelevant. Is there a way to get around that extra effort which is unnecessary in 95% of all cases?

Upvotes: 2

Views: 429

Answers (2)

Paul Kulchenko
Paul Kulchenko

Reputation: 26744

Number of returned values is not the same as the number of elements in the table built from returned values. It works in the example you have, but only because the example doesn't include any nil values.

In the general case when the returned values may include nil, it's almost always better to use select('#'...) instead:

print(#{(function() return 1, nil, 2 end)()})
print(select('#', (function() return 1, nil, 2 end)()))

This code prints 1 3 in Lua 5.1, but 3 3 in Lua 5.2 and Lua 5.3. Adding one more nil to the return values changes this to 1 4 under all these versions of Lua.

These functions can be used as wrappers that returns the number of return values and also return a list or a table with the values:

function wrap(...) return select('#', ...), ... end
function wrapt(...) return select('#', ...), {...} end

Using one of these functions, print(wrap((function() return 1, nil, 2, nil end)())) prints 4 1 nil 2 nil as expected.

Upvotes: 2

luther
luther

Reputation: 5544

Keep your function definition as it is and call it like this:

local values = {ascii(myString)}
local n = #values

Upvotes: 3

Related Questions