# 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 func 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 int 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 int argument number to blame in error message
  - expected string specification for acceptable argument types
  - actual argument passed
  - level int 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 int argument number
  - extramsg string additional text to append to message inside parentheses (optional)
  - level int call stack level to blame for the error (default 1)

  ### See also:

  - resulterror
  - extramsg_mismatch

  ### 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 func 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:

  say

  ### 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 number erroring container element index (optional)

  ### Returns:

  string formatted extramsg for this mismatch for argerror

  ### See also:

  - argerror
  - resulterror

  ### 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 int 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 boolean honor argcheck and argscheck calls (default true)
  - call boolean 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 int 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 int maximum number of bad things expected
  - actual int actual number of bad things that triggered the error

  ### See also:

  - argerror
  - resulterror
  - extramsg_mismatch

  ### 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 int, function or functable 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 int argument number
  - extramsg string additional text to append to message inside parentheses (optional)
  - level int 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 function or functable target function
  - env table new function environment
typesplit
  Split a typespec string into a table of normalized type names.
  - either string or table `"?bool|:nometa"` or `{"boolean", ":nometa"}`

generated by LDoc 1.4.3 Last updated 2018-09-03 17:48:42