Reputation: 2293
A framework I'm working on may be extended with Lua modules. The Lua sources for each module are compiled with a compiler of ours that's based on the official Lua interpreter and then saved as bytecode. Such modules must meet certain requirements:
-- Must be a non-empty string consisting only of characters in the range a-z
name = "foo"
-- Must not only be a number, but also an integer greater than zero
version = 1
It would be nice if the requirements could be checked when the Lua sources are compiled into the module. This would make life easier:
Checking that a certain value is of a certain type is not difficult:
// lua_getglobal returns the type of the value
int r = lua_getglobal(lua_state, "name");
if ( r == LUA_TSTRING )
{
// well done, dear module writer (well, must still check if the string contains
// only valid characters)
}
else if ( r == LUA_TNIL )
{
// error: `name' not defined
}
else
{
// hey you, `name' should be a string!
}
But how would one go about checking that a function takes a certain number of arguments and returns a table with certain fields?
-- must be defined with two parameters
function valid_function( arg1 , arg2 )
-- must return a table
return {
a = 17, -- with field `a', a number
b = "a" -- with field `b', a string
}
end
Note that I'm asking whether this is possible (and, if so, how) with the C API, unlike this question, which is about doing this from within Lua.
Upvotes: 2
Views: 752
Reputation: 69944
You cannot do that. Every Lua function can take any number of arguments and return any number of values, of any type.
I think the best you can do is write explicit type annotations somewhere (either in a comment or in something that appears at runtime) and then check that. There is also Typed Lua, which is an experimental Lua dialect with a static type system.
For example of how functions can receive any amount of arguments, if a function receives less arguments than it has parameters, the extra parameters get assigned to nil
. If you pass more arguments than the function has as parameters, the extra arguments are discarded.
function foo(x, y)
print(x,y)
end
foo() -- prints nil, nil
foo(1) -- prints 1, nil
foo(1,2) -- prints 1, 2
foo(1,2,3) -- prints 1, 2
Having the missing parameters be nil
is also commonly used to implement functions with optional parameters which means that a naive attempt at checking the number of arguments will conflict with this common Lua idiom:
function hello(name)
name = "mysterious stranger"
print("Hello, "..name.."!")
end
Return arguments are also flexible, just like the input arguments are:
function bar()
return 1, 2
end
local x = bar() -- second return value gets discarded
local x, y = bar()
local x, y, z = bar() - z gets assigned to `nil`
Many Lua functions also return a different number of arguments depending on a condition. For example, io.open
returns a single value (the file handle) if it could open the file or two values (nil followed by an error message) if it could not.
Upvotes: 4