Search code examples
luadynamic-function

Lua : Dynamically calling a function with arguments


Using Lua, I'm trying to dynamically call a function with parameters. I want to send a string to be parsed in a way that:

  • 1st argument is a class instance "Handle"
  • 2nd is the function to be called
  • All that is left are arguments

"modules" is a a table like { string=<instance of a class> }
split() is a simple parser that returns a table with indexed strings.

function Dynamic(msg)
    local args = split(msg, " ")
    module = args[1]
    table.remove(args, 1)
    if module then
        module = modules[module]
        command = args[1]
        table.remove(args, 1)
        if command then
            if not args then
                module[command]()
            else
                module[command](unpack(args))  -- Reference 1
            end
        else
            -- Function doesnt exist
        end
    else
        -- Module doesnt exist
    end
end

When I try this with "ignore remove bob", by "Reference 1", it tries to call "remove" on the instance associated with "ignore" in modules, and gives the argument "bob", contained in a table (with a single value).

However, on the other side of the call, the remove function does not receive the argument. I even tried to replace the "Reference 1" line with

module[command]("bob")

but I get the same result.

Here is the other function, which does not receive the argument "bob" :

function TIF_Ignore:remove(name)
    print(name)  -- Reference 2
    TIF_Ignore:rawremove(name)
    TIF_Ignore:rawremovetmp(name)
    print(title.. name.. " is not being ignored.")
end

I added "Reference 2" in my code when I was trying to figure out what was wrong. When I do "ignore remove bob", or when I replace the "unpack(args)" with "bob" on "Reference 1", the variable "name" in "remove" is still nil.


Solution

  • The declaration function TIF_Ignore:remove(name) is equivalent to function TIF_Ignore.remove(self, name). Note the use of colon in the first case, it adds extra hidden parameter to emulate OOP and classes. The way you call the function, you pass "bob" as the self parameter instead of name.

    To fix this you can make remove "static function" like this: function TIF_Ignore.remove(name). However, you'll also have to change rawremove and rawremovetmp in a similar fashion, both declaration and calling site. The other (easier) option is not to remove module from the args table, it should be the first parameter passed.