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")
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With