Reputation: 525
I have an empty table which I want to act as a "gateway" to another set of functions at another location.
tbl = {}
I want to pass called functions from this table to somewhere else as a string:
tbl.someMethod("hello")
I've tried this with limited success.
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)
How do I forward the undefined function through the table without it throwing errors?
Edit: More detail
I'm trying to define and call a function in a table in one call:
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)
This code does work but the first pcall will throw an error because the function hasn't been defined yet.
Say I wanted to use an library which I know updates quite a lot and keep my script compatible and this library may not be present on my computer. I would like to forward calls to this library across some interface but I still want to be able to call the functions in the same way.
--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)
Is this possible?
Edit 2:
Thanks @greatwolf !
This is my working test code.
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")
Upvotes: 3
Views: 457
Reputation: 20848
Okay, based on your updated details you want lua to translate this call
someLib.doSomething(name, age, telephone)
into
someOtherLib.invoke("someLib.doSomething", name, age, telephone)
behind the scenes. What you have is almost there, you just need to return the newly created function back:
__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
Now, if your someOtherLib
is just a table of functions, lhf's suggestion will work too
setmetatable(tbl, {__index = someOtherLib})
Now if your someOtherLib
provides someway to get the function you want to call without actually invoking it just yet, __index
can relay this without creating extra closure wrappers
__index = function(tbl, name)
tbl[name] = someOtherLib.getFuncByName(name)
return tbl[name]
end
The __call
metamethod is not needed here.
Upvotes: 3