lua call function from a string with function name

后端 未结 5 1988
感动是毒
感动是毒 2020-12-13 05:19

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() ?

相关标签:
5条回答
  • 2020-12-13 05:44

    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.

    0 讨论(0)
  • 2020-12-13 05:46

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

    0 讨论(0)
  • 2020-12-13 05:52

    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
    
    0 讨论(0)
  • 2020-12-13 05:52

    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, ...)
    
    0 讨论(0)
  • 2020-12-13 05:52

    Names are not unique, there can be many functions names foo in different namespaces. But _G['foo'] is foo in the global namespace.

    0 讨论(0)
提交回复
热议问题