Software and Other Stuff

09 Dec 2010

Lua's multiple arguments and the "select" function

When I first read about lua's select function I found it a little confusing.

According to lua's manual for version 5.1, select behaves as follows:

select (index, ยทยทยท)
If index is a number, returns all arguments after argument number
index.  Otherwise, index must be the string "#", and select returns
the total number of extra arguments it received.

That wasn't clear to me at first, but then I remembered lua sports real multiple arguments. I remark the word real because other languages like ruby don't really support returning multiple arguments. In ruby, if a method returns multiple arguments they are automatically packed into an array. Lua, in the other hand, has built in multiple arguments, which you can convert into a table if you really need to:

function multiple_args(...)
  local arguments = {...}  -- pack the arguments in a table
  -- do something --
  return unpack(arguments) -- return multiple arguments from a table (unpack)

Remembering the nature of lua's multiple arguments, and the fact that multiple arguments are not returned on a lua table dressed as an array, the description on the manual started to make sense.

The select function takes as "index" the index of the first argument that you want to retrieve, and any number of arguments afterward (the count of arguments starts at 1).

print(select(1, 1, 2, 3)) --> 1, 2, 3
print(select(2, 1, 2, 3)) --> 2, 3
print(select(3, 1, 2, 3)) --> 3
print(select(4, 1, 2, 3)) --> NOTHING

print(select(1, {1, 2, 3})) --> table
print(select(2, {1, 2, 3})) --> nothing

In the last two examples, the number of variable arguments is just one, consisting of a single table.

By the way, note another subtlety of lua: if you select more that the number of arguments available you get absolutely nothing!. Not even nil: nothing. If you try to pack NOTHING into a table, you get an empty table:

print(#{(function()end)()}) --> 0

Finally, if you pass "#" as index, the function returns a count of the multiple arguments provided:

print(select("#")) --> 0
print(select("#", {1, 2, 3})) --> 1 (single table as argument)
print(select("#", 1, 2, 3)) --> 3
print(select("#", {1,2,3}, 4, 5, {6,7,8}) --> 4 (a table, 2 numbers, another table)

Related Posts

28 Mar 2014
» Fun with Google's Apps Script! Batch Processing Gmail emails By Host
07 Oct 2013
» Graphs are Everywhere! An overview of GraphConnect San Francisco 2013
23 Jul 2013
» Using AngularJS with a Rails backend

The opinions expressed in this personal blog represent my own and not those of my employer. All data and information provided is for informational purposes only. This blog makes no representations as to accuracy, completeness, currentness, suitability, or validity of any information on this site and will not be liable for any errors, omissions, or delays in this information or any losses, injuries, or damages arising from its display or use. All information is provided on an as-is basis.  |  icons