Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lua call function from a string with function name

Tags:

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 ?

like image 863
Gregoire Avatar asked Nov 24 '09 16:11

Gregoire


People also ask

How do you call a function by name as a string?

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.

How do you call a function in Lua?

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.


2 Answers

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 
like image 108
gwell Avatar answered Sep 22 '22 00:09

gwell


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'].

like image 40
koniu Avatar answered Sep 20 '22 00:09

koniu