Is it possible in lua to execute a function from a string representing its name?
i.e: I have the string x = \"foo\"
, is it possible to do x()
?
It sounds like you want to do an 'eval', which is supported in Lua like so:
assert(loadstring(x))()
You'll probably want to concatenate the "()" onto x first, though.
I frequently put a bunch of functions in a table:
functions = {
f1 = function(arg) print("function one: "..arg) end,
f2 = function(arg) print("function two: "..arg..arg) end,
...,
fn = function(arg) print("function N: argh") end,
}
Then you can use a string as an table index and run your function like this
print(functions["f1"]("blabla"))
print(functions["f2"]("blabla"))
This is the result:
function one: blabla
function two: blablablabla
I find this to be cleaner than using loadstring()
. If you don't want to create a special function table you can use _G['foo']
.
To call a function in the global namespace (as mentioned by @THC4k) is easily done, and does not require loadstring()
.
x='foo'
_G[x]() -- calls foo from the global namespace
You would need to use loadstring()
(or walk each table) if the function in another table, such as if x='math.sqrt'
.
If loadstring()
is used you would want to not only append parenthesis with ellipse (...)
to allow for parameters, but also add return
to the front.
x='math.sqrt'
print(assert(loadstring('return '..x..'(...)'))(25)) --> 5
or walk the tables:
function findfunction(x)
assert(type(x) == "string")
local f=_G
for v in x:gmatch("[^%.]+") do
if type(f) ~= "table" then
return nil, "looking for '"..v.."' expected table, not "..type(f)
end
f=f[v]
end
if type(f) == "function" then
return f
else
return nil, "expected function, not "..type(f)
end
end
x='math.sqrt'
print(assert(findfunction(x))(121)) -->11
loadstring
is not the answer here. For starters you would need a return
in the string, and other details I won't go into.
THC4k has the right idea; if you have the function name in the variable x, then the call you want is
_G[x](arg1, arg2, ...)
Names are not unique, there can be many functions names foo in different namespaces. But _G['foo']
is foo
in the global namespace.