Lua:使用参数动态调用函数

3
使用Lua,我正在尝试动态调用带参数的函数。我想发送一个字符串以便进行解析,其中:
  • 第一个参数是类实例“Handle”
  • 第二个参数是要调用的函数
  • 剩下的都是参数
“modules”是一个类似于{ string=<类的实例> }的表格。
split()是一个简单的解析器,返回一个带有索引字符串的表格。
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

当我使用“忽略删除bob”进行测试时,在“参考1”中,它试图在模块中与“忽略”相关联的实例上调用“remove”,并提供包含一个值的表中的参数“bob”。
然而,在调用的另一侧,remove函数未收到该参数。我甚至尝试用以下代码替换“参考1”行:
module[command]("bob")

但我得到了相同的结果。

这是另一个函数,它不接收参数"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

当我试图找出问题所在时,我在代码中添加了“Reference 2”。当我执行“ignore remove bob”或者在“Reference 1”中用“bob”替换“unpack(args)”时,“remove”函数中的变量“name”仍然为nil。


你的代码看起来很好。"另一边"是什么样子? - Tuomas Pelkonen
函数'split'是什么样子的,因为它不是标准Lua的一部分。 - Tuomas Pelkonen
2个回答

3
如果您想调用使用冒号:语法定义的函数,您需要传递一个额外的参数,即它所期望的表格。由于您给出的特定示例未使用self,因此您可以切换到点.语法,但是如果您需要完全通用性,请参考以下代码:
function Dynamic(msg)
    local args   = split(msg, " ")
    local module = table.remove(args, 1)
    if module and modules[module] then
        module = modules[module]
        local command = table.remove(args, 1)
        if command then
            local command = module[command]
            command(module, unpack(args))
        else
            -- Function doesnt exist
        end
    else
        -- Module doesnt exist
    end
end

我还解决了一些小问题:

  • 变量应该是 local 的。
  • args 总是非空的。
  • 查找 modules[module] 可能会失败。
  • table.remove 返回被移除的元素,并且在空表上调用它也是可以的。

谢谢,你的回答帮助我指出了许多我不知道需要解决的其他问题! - Tipx

3
声明 function TIF_Ignore:remove(name) 等同于 function TIF_Ignore.remove(self, name)。请注意在第一种情况下使用了冒号,它添加了额外的隐藏参数以模拟OOP和类。调用函数的方式是将 "bob" 作为 self 参数传递,而不是 name
要解决这个问题,可以像这样使 remove 成为 "静态函数": function TIF_Ignore.remove(name)。然而,您还必须以类似的方式更改 rawremoverawremovetmp 的声明和调用站点。另一个(更容易)的选项是不从 args 表中删除 module,它应该是传递的第一个参数。

谢谢!我选择了这个答案作为“最佳答案”,因为你指出了问题。我对Lua不熟悉,我只想让它“正常工作”,而你做到了!谢谢! - Tipx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接