rwalli
rwalli

Reputation: 23

lua function including parameter in a table

I'm new to lua and want to store a function in a table with parameters given at "store time".

Tried this code but does not what I want (obviously).

local functable = {}
local function myfunc(x,y)
    print(x ,y)
end

table.insert(functable, {func = myfunc})
table.remove(functable).func("hello", "World")

I would like to store the variables at "insert" so I tried to store the parameters in the table:

functable = {}

function myfunc()
    print(functable[#functable].p1 ,functable[#functable].p2)
end

table.insert(functable, {func = myfunc, p1="Hello", p2="World"})
table.remove(functable).func()

but this code does not work.

Can someone point me to the right direction?

Upvotes: 2

Views: 188

Answers (3)

luther
luther

Reputation: 5544

Instead of storing myfunc, you really want to store a similar function that has no parameters. In other words, a closure:

local functable = {}

local function myfunc(x, y)
  print(x, y)
end

local function addArguments(f, ...)
  local args = {...}
  return function()
    return f(table.unpack(args))
  end
end

table.insert(functable, addArguments(myfunc, 'Hello', 'World'))
table.remove(functable)()

This solution differs from Egor's answer by using a closure rather than a table to bundle the function and the arguments.

Upvotes: 1

Egor   Skriptunoff
Egor Skriptunoff

Reputation: 974

This is a modification of Nifim's first variant:

functable = {}

local function myfunc(x,y)
   print(x, y)
end

local F_mt = {}

function F_mt:__call()
   return self.func(table.unpack(self.params))
end

local function F(obj)
   return setmetatable(obj, F_mt)
end

table.insert(functable, F{func = myfunc, params = {"Goodbye", "World~"}})
table.insert(functable, F{func = myfunc, params = {"Hello", "World!"}})

table.remove(functable)()
table.remove(functable)()

Upvotes: 1

Nifim
Nifim

Reputation: 5031

The issues with your code is that once you do table.remove your p1 and p2 cant be retrieved in myfunc using functable[#functable]. if you entered a second function you would see the print but the print would be with the params of your next function in the table.

table.insert(functable, {func = myfunc, p1="Goodbye", p2="World~"})
table.insert(functable, {func = myfunc, p1="Hello", p2="World!"})
table.remove(functable).func()

Output:

Goodbye World~


A solution i suggest is to set the params in the table and then apply them to your function as you call it:

functable = {}

local function myfunc(x,y)
    print(x ,y)
end

table.insert(functable, {func = myfunc, params = {"Goodbye", "World~"}})
table.insert(functable, {func = myfunc, params = {"Hello", "World!"}})

local action1 = table.remove(functable)
local action2 = table.remove(functable)

action1.func(table.unpack(action1.params))
action2.func(table.unpack(action2.params))

An alternative solution is to wrap your function and set the parameters up as upvalues.

Here is an example:

functable = {}

function myfunc(...)
    local params = {...}

    local function func()
        print(params[1] ,params[2])
    end

    return func
end

table.insert(functable, {func = myfunc("Goodbye", "World~")})
table.insert(functable, {func = myfunc("Hello", "World!")})

table.remove(functable).func()
table.remove(functable).func()

Upvotes: 1

Related Questions