Module std.debug
Additions to the core debug module.
The module table returned by `std.debug` also contains all of the entries from the core debug table. An hygienic way to import this module, then, is simply to override the core `debug` locally:
local debug = require "std.debug"
The behaviour of the functions in this module are controlled by the value of the global `_DEBUG`. Not setting `_DEBUG` prior to requiring **any** of stdlib's modules is equivalent to having `_DEBUG = true`.
The first line of Lua code in production quality projects that use stdlib should be either:
_DEBUG = false
or alternatively, if you need to be careful not to damage the global environment:
local init = require "std.debug_init" init._DEBUG = false
This mitigates almost all of the overhead of argument typechecking in stdlib API functions.
Functions
| DEPRECATED (version, name[, extramsg], fn) | Provide a deprecated function definition according to _DEBUG.deprecate. |
| DEPRECATIONMSG (version, name[, extramsg], level) | Format a deprecation warning message. |
| argcheck (name, i, expected, actual[, level=2]) | Check the type of an argument against expected types. |
| argerror (name, i[, extramsg[, level=1]]) | Raise a bad argument error. |
| argscheck (decl, inner) | Wrap a function definition with argument type and arity checking. |
| debug () | Equivalent to calling `debug.say (1, ...)` |
| extramsg_mismatch (expected, actual[, index]) | Format a type mismatch error. |
| parsetypes (types) | Compact permutation list into a list of valid types at each argument. |
| say ([n=1], ...) | Print a debugging message to `io.stderr`. |
| trace (event) | Trace function calls. |
Tables
| _DEBUG | Control std.debug function behaviour. |
Fields
| extramsg_toomany | Format a too many things error. |
| getfenv | Extend `debug.getfenv` to unwrap functables correctly. |
| resulterror | Raise a bad result error. |
| setfenv | Extend `debug.setfenv` to unwrap functables correctly. |
| typesplit | Split a typespec string into a table of normalized type names. |
Functions
Methods- DEPRECATED (version, name[, extramsg], fn)
-
Provide a deprecated function definition according to _DEBUG.deprecate.
You can check whether your covered code uses deprecated functions by
setting `_DEBUG.deprecate` to `true` before loading any stdlib modules,
or silence deprecation warnings by setting `_DEBUG.deprecate = false`.
Parameters:
- version string first deprecation release version
- name string function name for automatic warning message
- extramsg string additional warning text (optional)
- fn string deprecated function
Returns:
-
a function to show the warning on first call, and hand off to *fn*
Usage:
M.op = DEPRECATED ("41", "'std.functional.op'", std.operator)
- DEPRECATIONMSG (version, name[, extramsg], level)
-
Format a deprecation warning message.
Parameters:
- version string first deprecation release version
- name string function name for automatic warning message
- extramsg string additional warning text (optional)
- level string call stack level to blame for the error
Returns:
-
string
deprecation warning message, or empty string
Usage:
io.stderr:write (DEPRECATIONMSG ("42", "multi-argument 'module.fname'", 2))
- argcheck (name, i, expected, actual[, level=2])
-
Check the type of an argument against expected types.
Equivalent to luaL_argcheck in the Lua C API.
Call `argerror` if there is a type mismatch.
Argument `actual` must match one of the types from in `expected`, each of which can be the name of a primitive Lua type, a stdlib object type, or one of the special options below:
#table accept any non-empty table any accept any non-nil argument type file accept an open file object function accept a function, or object with a __call metamethod int accept an integer valued number list accept a table where all keys are a contiguous 1-based integer range #list accept any non-empty list object accept any std.Object derived type :foo accept only the exact string ":foo", works for any :-prefixed string
The `:foo` format allows for type-checking of self-documenting boolean-like constant string parameters predicated on `nil` versus `:option` instead of `false` versus `true`. Or you could support both:
argcheck ("table.copy", 2, "boolean|:nometa|nil", nometa)
A very common pattern is to have a list of possible types including "nil" when the argument is optional. Rather than writing long-hand as above, prepend a question mark to the list of types and omit the explicit "nil" entry:
argcheck ("table.copy", 2, "?boolean|:nometa", predicate)
Normally, you should not need to use the `level` parameter, as the default is to blame the caller of the function using `argcheck` in error messages; which is almost certainly what you want.
Parameters:
- name string function to blame in error message
- i string argument number to blame in error message
- expected string specification for acceptable argument types
- actual argument passed
- level string call stack level to blame for the error (default 2)
Usage:
local function case (with, branches) argcheck ("std.functional.case", 2, "#table", branches) ...
- argerror (name, i[, extramsg[, level=1]])
-
Raise a bad argument error.
Equivalent to luaL_argerror in the Lua C API. This function does not
return. The `level` argument behaves just like the core `error`
function.
Parameters:
- name string function to callout in error message
- i string argument number
- extramsg string additional text to append to message inside parentheses (optional)
- level string call stack level to blame for the error (default 1)
See also:
Usage:
local function slurp (file) local h, err = input_handle (file) if h == nil then argerror ("std.io.slurp", 1, err, 2) end ...
- argscheck (decl, inner)
-
Wrap a function definition with argument type and arity checking.
In addition to checking that each argument type matches the corresponding
element in the *types* table with `argcheck`, if the final element of
*types* ends with an ellipsis, remaining unchecked arguments are checked
against that type:
format = argscheck ("string.format (string, ?any...)", string.format)
A colon in the function name indicates that the argument type list does not have a type for `self`:
format = argscheck ("string:format (?any...)", string.format)
If an argument can be omitted entirely, then put its type specification in square brackets:
insert = argscheck ("table.insert (table, [int], ?any)", table.insert)
Similarly return types can be checked with the same list syntax as arguments:
len = argscheck ("string.len (string) => int", string.len)
Additionally, variant return type lists can be listed like this:
open = argscheck ("io.open (string, ?string) => file or nil, string", io.open)
Parameters:
- decl string function type declaration string
- inner string function to wrap with argument checking
Usage:
local case = argscheck ("std.functional.case (?any, #table) => [any...]", function (with, branches) ... end)
- debug ()
-
Equivalent to calling `debug.say (1, ...)`
See also:
Usage:
local debug = require "std.debug" debug "oh noes!"
- extramsg_mismatch (expected, actual[, index])
-
Format a type mismatch error.
Parameters:
- expected string a pipe delimited list of matchable types
- actual the actual argument to match with
- index string erroring container element index (optional)
Returns:
See also:
Usage:
if fmt ~= nil and type (fmt) ~= "string" then argerror ("format", 1, extramsg_mismatch ("?string", fmt)) end
- parsetypes (types)
-
Compact permutation list into a list of valid types at each argument.
Eliminate bracketed types by combining all valid types at each position
for all permutations of *typelist*.
Parameters:
- types list a normalized list of type names
Returns:
-
list
valid types for each positional parameter
- say ([n=1], ...)
-
Print a debugging message to `io.stderr`.
Display arguments passed through `std.tostring` and separated by tab
characters when `_DEBUG` is `true` and *n* is 1 or less; or `_DEBUG.level`
is a number greater than or equal to *n*. If `_DEBUG` is false or
nil, nothing is written.
Parameters:
- n list debugging level, smaller is higher priority (default 1)
- ... objects to print (as for print)
Usage:
local _DEBUG = require "std.debug_init"._DEBUG _DEBUG.level = 3 say (2, "_DEBUG table contents:", _DEBUG)
- trace (event)
-
Trace function calls.
Use as debug.sethook (trace, "cr"), which is done automatically
when `_DEBUG.call` is set.
Based on test/trace-calls.lua from the Lua distribution.
Parameters:
- event string event causing the call
Usage:
_DEBUG = { call = true } local debug = require "std.debug"
Tables
- _DEBUG
-
Control std.debug function behaviour.
To declare debugging state, set _DEBUG either to `false` to disable all
runtime debugging; to any "truthy" value (equivalent to enabling everything
except *call*, or as documented below.
Fields:
- argcheck string honor argcheck and argscheck calls (default true)
- call string do call trace debugging (default false)
- deprecate if `false`, deprecated APIs are defined, and do not issue deprecation warnings when used; if `nil` issue a deprecation warning each time a deprecated api is used; any other value causes deprecated APIs not to be defined at all (default nil)
- level string debugging level (default 1)
Usage:
_DEBUG = { argcheck = false, level = 9 }
Fields
- extramsg_toomany
-
Format a too many things error.
- bad string the thing there are too many of
- expected string maximum number of *bad* things expected
- actual string actual number of *bad* things that triggered the error
See also:
Usage:
if maxn (argt) > 7 then argerror ("sevenses", 8, extramsg_toomany ("argument", 7, maxn (argt))) end
- getfenv
-
Extend `debug.getfenv` to unwrap functables correctly.
- fn string, string or string target function, or stack level
- resulterror
-
Raise a bad result error.
Like argerror for bad results. This function does not
return. The `level` argument behaves just like the core `error`
function.
- name string function to callout in error message
- i string argument number
- extramsg string additional text to append to message inside parentheses (optional)
- level string call stack level to blame for the error (default 1)
Usage:
local function slurp (file) local h, err = input_handle (file) if h == nil then argerror ("std.io.slurp", 1, err, 2) end ...
- setfenv
-
Extend `debug.setfenv` to unwrap functables correctly.
- fn string or string target function
- env table new function environment
- typesplit
- Split a typespec string into a table of normalized type names.