Note that this question is about pure Lua. I do not have access to any module or the C side. Additionally, I can not use the IO, the OS or the debug library.
What I'm trying to make is a function that receives, as parameters:
By 'a callable value', I mean a value that can be called. This can be:
__call
metamethod)Here's an example of a callable table:
local t = {}
setmetatable(t, {
__call = function() print("Hi.") end
})
print(type(t)) --> table
t() --> Hi.
Here's the function:
function delay(seconds, func)
-- The second parameter is called 'func', but it can be anything that is callable.
coroutine.wrap(function()
wait(seconds) -- This function is defined elsewhere. It waits the ammount of time, in seconds, that it is told to.
func() -- Calls the function/table.
end)()
end
But I have a problem. I want the function to throw an error if the parameter 'func' is not callable.
I can check if it is a function. But what if it is a table with a metatable that allows calling?
If the metatable of the table is not protected by a __metatable
field, then, I can check the metatable to know if it is callable, but, otherwise, how would I do it?
Note that I have also thought about trying to call the 'func' parameter with pcall
, to check if it is callable, but to do that, I need to call it prematurely.
Basically, here's the problem: I need to know if a function/table is callable, but without trying to call it.
The degree of accuracy and precision of a measuring system are related to the uncertainty in the measurements. Uncertainty is a quantitative measure of how much your measured values deviate from a standard or expected value.
The main difference between errors and uncertainties is that an error is the difference between the actual value and the measured value, while an uncertainty is an estimate of the range between them, representing the reliability of the measurement.
Accuracy and precision are alike only in the fact that they both refer to the quality of measurement, but they are very different indicators of measurement. Accuracy is the degree of closeness to true value. Precision is the degree to which an instrument or process will repeat the same value.
Use the IF function, one of the logical functions, to return one value if a condition is true and another value if it's false. For example: =IF(A2>B2,"Over Budget","OK") =IF(A2=B2,B4-A4,"")
In general, if the metatable does not want you to be able to get it (by defining __metatable
to being something special), then you're not going to get it. Not from Lua.
However, if you want to cheat, you can always use debug.getmetatable
, which will return the metatable associated with that object.
You don't have to prematurely call anything with pcall
. Observe:
pcall(function(...) return PossibleFunction(...) end, <insert arguments here>)
function iscallable(x)
if type(x) == 'function' then
return true
elseif type(x) == 'table' then
-- It would be elegant and quick to say
-- `return iscallable(debug.getmetatable(x))`
-- but that is actually not quite correct
-- (at least in my experiments), since it appears
-- that the `__call` metamethod must be a *function* value
-- (and not some table that has been made callable)
local mt = debug.getmetatable(x)
return type(mt) == "table" and type(mt.__call) == "function"
else
return false
end
end
return iscallable
Then you can do
> = iscallable(function() end)
true
> = iscallable({})
false
> = iscallable()
false
> = iscallable(nil)
false
> x = {}
> setmetatable(x, {__call=function() end})
> = iscallable(x)
true
If you don't have access to the debug library, then you may have trouble being totally accurate since you can mess with metatables. You could use pcall
but its hard to separate out the errors properly. Even if you search for a particular error string as in the other answer here, that might be because of something inside the function being called not being callable, not this particular value not being callable, if that makes sense.
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