This library declares a checks()
function and a checkers
table, which
allow to check the parameters passed to a Lua function in a fast and
unobtrusive way.
Function checks(type_1, ..., type_n)
,
when called directly inside function fn
,
checks that fn
's 1st argument conforms to type_1
,
2nd argument conforms to type_2
, etc.
Type specifiers are strings or tables, and if the arguments passed
to fn
don't conform to their specification, a proper error message is produced,
pinpointing the call to fn
as the faulty expression.
The type is simply type(arg)
, such as 'table'
, 'number'
etc.
function fn_string(x)
checks('string')
end
fn_string('foo') -- ok
fn_string(99) -- error: bad argument #1 to fn_string (string expected, got number)'
An arbitrary name, which is stored in the __type
field of the argument metatable
function fn_color(x)
checks('color')
end
local blue = setmetatable({0, 0, 255}, {__type = 'color'})
fn_color(blue) -- ok
fn_color({}) -- error: bad argument #1 to fn_color (color expected, got table)'
The function would be stored in the checkers
global table.
This function is called with original value passed to fn
and must return true
if the value is valid.
function fn_positive(x)
checks('positive')
end
function checkers.positive(p)
return (type(p) == 'number') and (p > 0)
end
fn_positive(42) -- ok
fn_positive(-1) -- error: bad argument #1 to fn_positive (positive expected, got number)'
Moreover, types can be prefixed with a question mark ?
, which makes them optional.
For instance, '?table'
accepts tables as well as nil
values.
A '?'
type alone accepts anything. It is mainly useful as a placeholder
to skip an argument which doesn't need to be checked.
Finally, several types can be accepted,
if their names are concatenated with a bar |
between them.
For instance, 'table|number'
accepts tables as well as numbers.
It can be combined with the question mark,
so '?table|number'
accepts tables, numbers and nil values.
Question mark is not equivalent to combination with 'nil'
type:
msgpack.NULL
is a valid value for '?number'
, but not for 'nil|number'
combination.
The type qualifier may be a table.
In this case the argument is checked to conform to '?table'
type, and its content is validated.
Table values are validated against type qualifiers as described above.
Table keys, which are not mentioned in checks
, are validated against 'nil'
type.
Table type qualifiers may be recursive and use tables too.
function fn_opts(options)
checks({
my_string = '?string',
my_number = '?number',
})
end
fn_opts({my_string = 's'}) -- ok
fn_opts({my_number = 101}) -- ok
fn_opts({my_number = 'x'}) -- error: bad argument options.my_number to fn_opts (?number expected, got string)'
fn_opts({bad_field = true}) -- error: unexpected argument options.bad_field to fn_opts
When the optional argument is validated with the table type qualifier, its value is set to an empty table. Thus it's safe to do:
function fn(options)
checks({timeout = '?number'})
options.timeout = options.timeout or 5.0
end
fn() -- ok
Functions with variable number of arguments are supported:
function fn_varargs(arg1, ...)
checks('string')
end
fn_varargs('s') -- ok
fn_varargs('s', 1) -- ok
fn_varargs('s', {}) -- ok
fn_varargs(42) -- error: bad argument #1 to fn_varargs (string expected, got number)'
This library was originally a part of luasched. Now it is a dependency for luacheck.