3

我有一个空表,我想将它作为另一个位置的另一组函数的“网关”。

tbl = {}

我想将此表中的调用函数作为字符串传递到其他地方:

tbl.someMethod("hello")

我已经尝试过,但成功有限。

hand = {
    __index = function(tbl, name)
      hand[name] = function(...) 
          passToSomewhere(name, ...)
      end
    end,
    __call = function(tbl, name, ...)
        hand[name](...)
    end
}
setmetatable(tbl, hand)
tbl.someFunction("hello!", someTbl, someNumber)

如何通过表转发未定义的函数而不会引发错误?

编辑:更多细节

我试图在一次调用中定义和调用表中的函数:

tbl = {}

hand = {
  __index = function(tbl, name)
    print(name)
    tbl[name] = function(...)
      print(...)
    end
  end
}
setmetatable(tbl, hand)

s,e = pcall(tbl.help,"banana","goat")
print(s)

s,e = pcall(tbl.help,"banana","goat")
print(s)

此代码确实有效,但第一个 pcall 将引发错误,因为尚未定义该函数。

假设我想使用一个我知道更新很多的库并保持我的脚本兼容,并且这个库可能不存在于我的计算机上。我想通过某个接口转发对该库的调用,但我仍然希望能够以相同的方式调用这些函数。

--For example I would like to call this function like this:
someLib.doSomething(name, age, telephone)

--Instead of passing it through another function:
someOtherLib.invoke("someLib.doSomething", name, age, telephone)

这可能吗?

编辑2:

谢谢@greatwolf!

这是我的工作测试代码。

tbl = {}

hand = {
  __index = function(tbl, name)
    tbl[name] = function(...)
      return print(name, ...)
    end
    return rawget(tbl, name) 
  end
}
setmetatable(tbl, hand)

tbl.help("banana","goat")
4

1 回答 1

3

好的,根据您更新的详细信息,您希望 lua 翻译此调用

someLib.doSomething(name, age, telephone)

进入

someOtherLib.invoke("someLib.doSomething", name, age, telephone)

在幕后。你所拥有的几乎就在那里,你只需要返回新创建的函数:

__index = function(tbl, name)
  tbl[name] = function(...)
    return someOtherLib.invoke("someLib."..name, ...)
  end
  -- return tbl[name] works too, I used rawget to indicate 
  -- no further __index lookup should be done
  return rawget(tbl, name) 
end

现在,如果你someOtherLib只是一个函数表,lhf 的建议也可以

setmetatable(tbl, {__index = someOtherLib})

现在,如果您someOtherLib提供了某种方式来获取您想要调用的函数而不实际调用它,__index则可以在不创建额外的闭包包装器的情况下中继它

__index = function(tbl, name)
  tbl[name] = someOtherLib.getFuncByName(name)
  return tbl[name]
end

这里__call不需要元方法。

于 2015-01-20T08:56:19.190 回答