How to 'unpack' table into function arguments
Asked Answered
F

3

36

I'm trying to call a function in Lua that accepts multiple 'number' arguments

function addShape(x1, y1, x2, y2 ... xn, yn)

and I have a table of values which I'd like to pass as arguments

values = {1, 1, 2, 2, 3, 3}

Is it possible to dynamically 'unpack' (I'm not sure if this is the right term) these values in the function call? Something like..

object:addShape(table.unpack(values))

Equivalent to calling:

object:addShape(1, 1, 2, 2, 3, 3)

Apologies if this is a totally obvious Lua question, but I can't for the life of me find anything on the topic.


UPDATE

unpack(values) doesn't work either (delving into the method addShape(...) and checking the type of the value passed reveals that unpackis resulting in a single string.

Fascinate answered 16/3, 2014 at 6:45 Comment(0)
S
44

You want this:

object:addShape(unpack(values))

See also: http://www.lua.org/pil/5.1.html

Here's a complete example:

shape = {
  addShape = function(self, a, b, c)
    print(a)
    print(b)
    print(c)
  end
}

values = {1, 2, 3}
shape:addShape(unpack(values))
Supernaturalism answered 16/3, 2014 at 6:48 Comment(11)
I should have added, I initially tried just unpack but this does not work either - the type of the argument being passed becomes a single stringFascinate
Try doing exactly what they show in the documentation I linked. Let us know if that works or is not what you want.Supernaturalism
I've looked into the addShape method and checked the type of .... It's a string - the docs seem to state exactly what I want, but I don't know why unpacking values is returning a stringFascinate
What version of Lua are you using?Supernaturalism
5.2 (JNLua), though I've also tried 5.1 to no avail.Fascinate
I added a complete example, tested on Lua 5.2.Supernaturalism
There is no other way except writing your own unpack( ) or using that native functionality. Should work.Hemelytron
Where do you get your values array from? Bet type(values[1]) is "string". ... has no type, but passing it to type is like passing the first var-arg parameter.Nonintervention
@Nonintervention that was the exact issue - an errant rounding function returning a string. Derp. Thank you and @John Zwinck.Fascinate
@Nik-Lz: With such a vague statement no one can help you. The code was tested on Lua 5.2 and does work.Supernaturalism
@Nikos: just for reference, table.unpack [should work in Lua 5.2 and later #25794864Tortoni
R
16

Whoever comes here and has Lua version > 5.1 unpack is moved into the table library so you can use: table.unpack

For more info: https://www.lua.org/manual/5.2/manual.html

Rn answered 21/7, 2021 at 6:12 Comment(1)
Newest version of LuaJIT (2.1.0-beta3) does not support table.unpack as a default, you have to use unpack instead or build it with DLUAJIT_ENABLE_LUA52COMPAT, see here.Sign
C
-7

This is not an answer about unpack, but a suggestion to use a different technique. Instead, do

function object:addShape(values)
    for i,v in ipairs(values) do 
        x,y = v.x, v.y
        ...
    end
end

function getPairs(values)
    xyPairs = {}
    for i=1,#values,2 do 
        v = {x=values[i], y=values[i+i] }
        table.insert(xyPair, v)
    end
    return xyPairs
end

values = {1, 1, 2, 2, 3, 3}
object:addShape(getPairs(values))

The amount of work to be done should be similar as unpacking and the additional processing you will have to do in addShape() to support variable number of named arguments.

Codd answered 16/3, 2014 at 16:17 Comment(2)
-1 for this solution. Not only do you create a new table for calling the function getPairs() but you also create a new table for every pair of values in the passed in parameter. This is exceptionally expensive compared to using unpack().Arabesque
I realized that others could learn from my mistake and Simon's comment so I'm going to leave it there as an example of what not to do :)Codd

© 2022 - 2024 — McMap. All rights reserved.