lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Quoth Coda Highland <chighland@gmail.com>, on 2013-02-14 18:06:46 -0800:
> > This is not true in general, though it's true much of the time.
> > In a context that expects exactly one value, such as __index
> > return values, returning nothing gets adjusted to a single nil.
> > So they are the same in this case.
> 
> With the exception of MULTRET in the C API, what cases am I forgetting about?

Variable number of return values is possible in Lua itself as well.  In
particular, a function call at the tail of an argument list will
have all of its returned values passed as arguments.  Imagine:

    function paranoid_format(fmt, ...)
        if compute_format_arity(fmt) ~= select('#', ...) then
            error('kaboom')
        end
        -- ...
    end

    function find_foo(key)
        if foo1.test(key) then return foo1.result(key) end
        if foo2.test(key) then return foo2.result(key) end
        -- No explicit nil return!
    end

    -- Later that night...
    paranoid_format(format_with_arity_1, find_foo('nonexistent_foo'))
    -- Kaboom!  paranoid_format gets zero varargs rather than one.

The same thing applies to the tail end of a return expression, which means
that the number of return values propagates upward through the call stack
when one function returns the result of another.

You can prevent this by using a second pair of parentheses to explicitly
adjust the number of results to one.  In most positions (RHS of assignments,
return value thrown away, most nested expression positions), the number of
results is implicitly adjusted, usually to one---but if you're designing
an API in Lua, for instance, be clear about whether you rely on this from
the caller.

The other case of variable return count is table constructors, but it
doesn't matter in that case because trailing nils in a table constructor
do nothing.  :-)

   ---> Drake Wilson