Lua - Execute a Function Stored in a Table

brain56 picture brain56 · Jun 17, 2013 · Viewed 25.7k times · Source

I was able to store functions into a table. But now I have no idea of how to invoke them. The final table will have about 100 calls, so if possible, I'd like to invoke them as if in a foreach loop. Thanks!

Here is how the table was defined:

game_level_hints = game_level_hints or {}
game_level_hints.levels = {}
game_level_hints.levels["level0"] = function()
    return
    {
        [on_scene("scene0")] =
        {
            talk("hint0"),
            talk("hint1"),
            talk("hint2")
        },
        [on_scene("scene1")] =
        {
            talk("hint0"),
            talk("hint1"),
            talk("hint2")
        }
    }
end

Aaand the function definitions:

function on_scene(sceneId)
    -- some code
    return sceneId
end

function talk(areaId)
    -- some code
    return areaId
end

EDIT:

I modified the functions so they'll have a little more context. Basically, they return strings now. And what I was hoping to happen is that at then end of invoking the functions, I'll have a table (ideally the levels table) containing all these strings.

Answer

Paul Kulchenko picture Paul Kulchenko · Jun 17, 2013

Short answer: to call a function (reference) stored in an array, you just add (parameters), as you'd normally do:

local function func(a,b,c) return a,b,c end
local a = {myfunc = func}
print(a.myfunc(3,4,5)) -- prints 3,4,5

In fact, you can simplify this to

local a = {myfunc = function(a,b,c) return a,b,c end}
print(a.myfunc(3,4,5)) -- prints 3,4,5

Long answer: You don't describe what your expected results are, but what you wrote is likely not to do what you expect it to do. Take this fragment:

game_level_hints.levels["level0"] = function()
    return
    {
        [on_scene("scene0")] =
        {
            talk("hint0"),
        }
    }
end

[This paragraph no longer applies after the question has been updated] You reference on_scene and talk functions, but you don't "store" those functions in the table (since you explicitly referenced them in your question, I presume the question is about these functions). You actually call these functions and store the values they return (they both return nil), so when this fragment is executed, you get "table index is nil" error as you are trying to store nil using nil as the index.

If you want to call the function you stored in game_level_hints.levels["level0"], you just do game_level_hints.levels["level0"]()