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()
?
If yes what is the syntax ?
There are two methods to call a function from string stored in a variable. The first one is by using the window object method and the second one is by using eval() method. The eval() method is older and it is deprecated.
The API protocol to call a function is simple: First, you push the function to be called; second, you push the arguments to the call; then you use lua_pcall to do the actual call; finally, you pop the results from the stack.
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
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']
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With