Reputation: 23
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
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
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
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