2

I have stumbled on strange behaviour of lua. Code example:

function foo()
    local t = {'a', 'b', 'c'}
    return unpack(t)
end

function bar()
    local t = {'x', 'y'}
    return unpack(t)
end

b = { foo(), bar() }

for k,v in pairs(b) do
    print(k,v)
end

Result of this code is:

1   a
2   x
3   y

So, results from foo() are all discarded except the first element. Question is, why some elements are discarded? I have briefly checked lua 5.2 manual, but I don't see explanation for this behaviour.

1 Answer 1

10

Question is, why some elements are discarded?

Because that's how Lua works. Expressions that result in multiple values (function calls and ...), when used in the context of a list of things (such as a table constructor or a function call argument list) will only add all of their values to that list if it is the last element of the list.

So:

{foo, ...}

Will put all of the varargs at the end.

{..., foo}

Will only put the first of the varargs into the table.

If you want to bundle multiple function calls like this, you have to use a function that will table.insert each element into the list individually.

Sign up to request clarification or add additional context in comments.

2 Comments

How inconvenient. I hope, there were important purposes to make this part of language in such unintuitive way. Anyway, thanks for the quick answer. Now I know that I haven't made some stupid little error.
Yes there are VERY important purposes. A function may return any number of results, and may return different number of results on different invocations. This is used to mark error conditions - in case of error you just return nil, errorString. Imagine you wanted to call io.open on multiple filenames - you can expect every element to be either nil or a file handle. If multiple results did expand, you would have to handle the special case of error strings suddenly appearing in the array. Also, the number of returned values cannot be known at compile time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.