# Module `std.normalize`

Normalize API differences between supported Lua implementations.

Respecting the values set in the `std._debug` settings module, inject deterministic identically behaving cross-implementation low-level functions into the callers environment.

Writing Lua libraries that target several Lua implementations can be a frustrating exercise in working around lots of small differences in APIs and semantics they share (or rename, or omit). normalize provides the means to simply access deterministic implementations of those APIs that have the the same semantics across all supported host Lua implementations. Each function is as thin and fast an implementation as is possible within that host Lua environment, evaluating to the Lua C implementation with no overhead where host semantics allow.

The core of this module is to transparently set the environment up with a single API (as opposed to requiring caching functions from a module table into module locals):

    local _ENV = require 'std.normalize' {
       'package',
       'std.prototype',
       strict = 'std.strict',
    }

It is not yet complete, and in contrast to the kepler project lua-compat libraries, neither does it attempt to provide you with as nearly compatible an API as is possible relative to some specific Lua implementation - rather it provides a variation of the "lowest common denominator" that can be implemented relatively efficiently in the supported Lua implementations, all in pure Lua.

At the moment, only the functionality used by stdlib is implemented.

## Functions

argerror (name, i[, extramsg[, level=1]]) | Raise a bad argument error.
getfenv (fn) | Get a function or functor environment.
getmetamethod (x, n) | Return named metamethod, if callable, otherwise `nil`.
ipairs (t) | Iterate over elements of a sequence, until the first `nil` value.
len (x) | Deterministic, functional version of core Lua `#` operator.
load (ld, source) | Load a string or a function, just like Lua 5.2+.
pack (...) | Return a list of given arguments, with field `n` set to the length.
pairs (t) | Like Lua `pairs` iterator, but respect `__pairs` even in Lua 5.1.
rawlen (x) | Length of a string or table object without using any metamethod.
setfenv (fn, env) | Set a function or functor environment.
str (x) | Return a compact stringified representation of argument.
unpack (t[, i=1[, j=len(t)]]) | Either `table.unpack` in newer-, or `unpack` in older Lua implementations.
xpcall (f, errh, ...) | Support arguments to a protected function call, even on Lua 5.1.
math.tointeger (x) | Convert to an integer and return if possible, otherwise `nil`.
math.type (x) | Return 'integer', 'float' or `nil` according to argument type.
os.exit (status) | Exit the program.
package.searchpath (name, path[, sep='.'[, rep=`package.dirsep`]]) | Searches for a named file in a given path.
string.render (x, vfns[, roots]) | Low-level recursive data to string rendering.
table.keys (t) | Return an unordered list of all keys in a table.
table.merge (t[, u={}]) | Destructively merge keys and values from one table into another.

## Tables

package | Package module constants for `package.config` substrings.

## Metamethods

__call (env[, level=1]) | Normalize caller's lexical environment.
__index (name) | Lazy loading of normalize modules.

## Types

RenderFns | Table of functions for string.render.
RenderElem (x) | Type of function for uniquely stringifying rendered element.
RenderTerm (x) | Type of predicate function for terminal elements.
RenderSort (keys) | Type of function for sorting keys of a recursively rendered element.
RenderOpen (x) | Type of function to get string for before first element.
RenderClose (x) | Type of function te get string for after last element.
RenderPair (x, kp, vp, k, v, kstr, vstr, seqp) | Type of function to render a key value pair.
RenderSep (x, kp, vp, kn, vn, seqp) | Type of function to render a separator between pairs.

## Functions

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)

  ### Usage:

      local function slurp(file)
         local h, err = input_handle(file)
         if h == nil then
             argerror('std.io.slurp', 1, err, 2)
         end
         ...

getfenv (fn)
  Get a function or functor environment.

  This version of getfenv works on all supported Lua versions, and knows how to unwrap functors (table's with a function valued `__call` metamethod).

  ### Parameters:

  - fn function or int

    stack level, C or Lua function or functor

        to act on

  ### Returns:

  table the execution environment of fn

  ### Usage:

      callers_environment = getfenv(1)

getmetamethod (x, n)
  Return named metamethod, if callable, otherwise `nil`.

  ### Parameters:

  - x item to act on
  - n string name of metamethod to look up

  ### Returns:

  function or nil

  metamethod function, or `nil` if no

      metamethod

  ### Usage:

      normalize = getmetamethod(require 'std.normalize', '__call')

ipairs (t)
  Iterate over elements of a sequence, until the first `nil` value.

  Returns successive key-value pairs with integer keys starting at 1, up to the index returned by the `__len` metamethod if any, or else up to last non-`nil` value.

  Unlike Lua 5.1, any `__index` metamethod is respected.

  Unlike Lua 5.2+, any `__ipairs` metamethod is ignored!

  ### Parameters:

  - t table table to iterate on

  ### Returns:

  1. function iterator function
  2. table t the table being iterated over
  3. int the previous iteration index

  ### Usage:

      t, u = {}, {}
      for i, v in ipairs {1, 2, nil, 4} do t[i] = v end
      assert(len(t) == 2)

      for i, v in ipairs(pack(1, 2, nil, 4)) do u[i] = v end
      assert(len(u) == 4)

len (x)
  Deterministic, functional version of core Lua `#` operator.

  Respects `__len` metamethod (like Lua 5.2+), or else if there is a `__tostring` metamethod return the length of the string it returns. Otherwise, always return one less than the lowest integer index with a `nil` value in x, where the `#` operator implementation might return the size of the array part of a table.

  ### Parameters:

  - x item to act on

  ### Returns:

  int the length of x

  ### Usage:

      x = {1, 2, 3, nil, 5}
      --> 5 3
      print(#x, len(x))

load (ld, source)
  Load a string or a function, just like Lua 5.2+.

  ### Parameters:

  - ld string or function chunk to load
  - source string name of the source of ld

  ### Returns:

  function a Lua function to execute ld in global scope.

  ### Usage:

      assert(load 'print "woo"')()

pack (...)
  Return a list of given arguments, with field `n` set to the length.

  The returned table also has a `__len` metamethod that returns `n`, so `ipairs` and `unpack` behave sanely when there are `nil` valued elements.

  ### Parameters:

  - ... tuple to act on

  ### Returns:

  table

  packed list of ... values, with field `n` set to

      number of tuple elements (including any explicit `nil` elements)

  ### See also:

  unpack

  ### Usage:

      --> 5
      len(pack(nil, 2, 5, nil, nil))

pairs (t)
  Like Lua `pairs` iterator, but respect `__pairs` even in Lua 5.1.

  ### Parameters:

  - t table table to act on

  ### Returns:

  1. function iterator function
  2. table t, the table being iterated over
  3. the previous iteration key

  ### Usage:

      for k, v in pairs {'a', b='c', foo=42} do process(k, v) end

rawlen (x)
  Length of a string or table object without using any metamethod.

  ### Parameters:

  - x string or table object to act on

  ### Returns:

  int raw length of x

  ### Usage:

      --> 0
      rawlen(setmetatable({}, {__len=function() return 42}))

setfenv (fn, env)
  Set a function or functor environment.

  This version of setfenv works on all supported Lua versions, and knows how to unwrap functors.

  ### Parameters:

  - fn function or int

    stack level, C or Lua function or functor

        to act on

  - env table new execution environment for fn

  ### Returns:

  function function acted upon

  ### Usage:

      function clearenv(fn) return setfenv(fn, {}) end

str (x)
  Return a compact stringified representation of argument.

  ### Parameters:

  - x item to act on

  ### Returns:

  string compact string representing x

  ### Usage:

      -- {baz,5,foo=bar}
      print(str{foo='bar','baz', 5})

unpack (t[, i=1[, j=len(t)]])
  Either `table.unpack` in newer-, or `unpack` in older Lua implementations.

  ### Parameters:

  - t table table to act on
  - i int first index to unpack (default 1)
  - j int last index to unpack (default len(t))

  ### Returns:

  ... values of numeric indices of t

  ### See also:

  pack

  ### Usage:

      local a, b, c = unpack(pack(nil, 2, nil))
      assert(a == nil and b == 2 and c == nil)

xpcall (f, errh, ...)
  Support arguments to a protected function call, even on Lua 5.1.

  ### Parameters:

  - f function protect this function call
  - errh function

    error object handler callback if f raises

        an error

  - ... arguments to pass to f

  ### Returns:

  ... all return values from f follow

  ### Or

  1. boolean `false` when `f(...)` raised an error
  2. string error message

  ### Or

  boolean `true` when `f(...)` succeeded

  ### Usage:

      -- Use errh to get a backtrack after curses exits abnormally
      xpcall(main, errh, arg, opt)

math.tointeger (x)
  Convert to an integer and return if possible, otherwise `nil`.

  ### Parameters:

  - x object to act on

  ### Returns:

  integer x converted to an integer if possible

  ### Or

  `nil` otherwise
math.type (x)
  Return 'integer', 'float' or `nil` according to argument type.

  To ensure the same behaviour on all host Lua implementations, this function returns 'float' for integer-equivalent floating values, even on Lua 5.3.

  ### Parameters:

  - x object to act on

  ### Returns:

  string 'integer', if x is a whole number

  ### Or

  string 'float', for other numbers

  ### Or

  `nil` otherwise
os.exit (status)
  Exit the program.

  ### Parameters:

  - status bool or number[opt=true] report back to parent process

  ### Usage:

      exit(len(records.processed) > 0)

package.searchpath (name, path[, sep='.'[, rep=`package.dirsep`]])
  Searches for a named file in a given path.

  For each `package.pathsep` delimited template in the given path, search for an readable file made by first substituting for sep with `package.dirsep`, and then replacing any `package.pathmark` with the result. The first such file, if any is returned.

  ### Parameters:

  - name string name of search file
  - path string `package.pathsep` delimited list of full path templates
  - sep string name component separator (default '.')
  - rep string sep replacement in template (default `package.dirsep`)

  ### Returns:

  string

  first template substitution that names a file

      that can be opened in read mode

  ### Or

  1. `nil`
  2. string error message listing all failed paths
string.render (x, vfns[, roots])
  Low-level recursive data to string rendering.

  ### Parameters:

  - x data to be renedered
  - vfns RenderFns table of virtual functions to control rendering
  - roots table used internally for cycle detection (optional)

  ### Returns:

  string a text recursive rendering of x using vfns

  ### Usage:

      function printarray(x)
         return render(x, arrayvfns)
      end

table.keys (t)
  Return an unordered list of all keys in a table.

  ### Parameters:

  - t table table to operate on

  ### Returns:

  table an unorderd list of keys in t

  ### Usage:

      --> {'key2', 1, 42, 2, 'key1'}
      keys{'a', 'b', key1=1, key2=2, [42]=3}

table.merge (t[, u={}])
  Destructively merge keys and values from one table into another.

  ### Parameters:

  - t table take fields from this table
  - u table and copy them into here, unless they are set already (default {})

  ### Returns:

  table u

  ### Usage:

      --> {'a', 'b', d='d'}
      merge({'a', 'b'}, {'c', d='d'})

## Tables

package
  Package module constants for `package.config` substrings.

  ### Fields:

  - dirsep string directory separator in path elements
  - execdir string replaced by the executable's directory in a path
  - igmark string

    ignore everything before this when building

        `luaopen_` function name

  - pathmark string mark substitution points in a path template
  - pathsep string element separator in a path template

## Metamethods

__call (env[, level=1])

  Normalize caller's lexical environment.

  Using 'std.strict' when available and selected, otherwise a (Lua 5.1 compatible) function to set the given environment.

  With an empty table argument, the core (not-table) normalize functions are loaded into the callers environment. For consistent behaviour between supported host Lua implementations, the result must always be assigned back to `_ENV`. Additional core modules must be named to be loaded at all (i.e. no 'debug' table unless it is explicitly listed in the argument table).

  Additionally, external modules are loaded using `require`, with `.` separators in the module name translated to nested tables in the module environment. For example 'std.prototype' in the usage below will add to the environment table the equivalent of:

         local prototype = require 'std.prototype'

  Alternatively, you can assign a loaded module symbol to a specific environment table symbol with `key=value` syntax. For example the the 'math.tointeger' from the usage below is equivalent to:

         local int = require 'std.normalize.math'.tointeger

  Compare this to loading the non-normalized implementation from the host Lua with a table entry such as:

         int = require 'math'.tointeger,

  Finally, explicit string assignment to ALLCAPS keys are not loaded from modules at all, but behave as a constant string assignment:

         INT = 'math.tointeger',

  ### Parameters:

  - env table environment table
  - level int

    stack level for `setfenv`, 1 means set

        caller's environment

    (default 1)

  ### Returns:

  table

  env with this module's functions merge id. Assign

      back to `_ENV`

  ### Usage:

      local _ENV = require 'std.normalize' {
         'string',
         'std.prototype',
         int = 'math.tointeger',
      }

__index (name)
  Lazy loading of normalize modules. Don't load everything on initial startup, wait until first attempt to access a submodule, and then load it on demand.

  ### Parameters:

  - name string submodule name

  ### Returns:

  table or nil

  the submodule that was loaded to satisfy the missing

      `name`, otherwise `nil` if nothing was found

  ### Usage:

      local version = require 'std.normalize'.version

## Types

RenderFns
  Table of functions for string.render.

  ### Fields:

  - elem RenderElem return unique string representation of an element
  - term RenderTerm

    return true for elements that should not be

        recursed

  - sort RenderSort return list of keys in order to be rendered
  - open RenderOpen return a string for before first element of a table
  - close RenderClose return a string for after last element of a table
  - pair RenderPair

    return a string rendering of a key value pair

        element

  - sep RenderSep return a string to render between elements

  ### See also:

  string.render

  ### Usage:

      arrayvfns = {
        elem = tostring,
        term = function(x)
           return type(x) ~= 'table' or getmetamethod(x, '__tostring')
        end,
        sort = function(keys)
           local r = {}
           for i = 1, #keys do
              if type(keys[i]) == 'number' then r[#r + 1] = keys[i] end
           end
           return r
        end,
        open = function(_) return '[' end,
        close = function(_) return ']' end,
        pair = function(x, kp, vp, k, v, kstr, vstr, seqp)
           return seqp and vstr or ''
        end,
        sep = function(x, kp, vp, kn, vn, seqp)
           return seqp and kp ~= nil and kn ~= nil and ', ' or ''
        end,
      )

RenderElem (x)
  Type of function for uniquely stringifying rendered element.

  ### Parameters:

  - x element to operate on

  ### Returns:

  string stringified x
RenderTerm (x)
  Type of predicate function for terminal elements.

  ### Parameters:

  - x element to operate on

  ### Returns:

  bool

  true for terminal elements that should be rendered

      immediately

RenderSort (keys)
  Type of function for sorting keys of a recursively rendered element.

  ### Parameters:

  - keys table

    list of table keys, it's okay to mutate and return

        this parameter

  ### Returns:

  table sorted list of keys for pairs to be rendered
RenderOpen (x)
  Type of function to get string for before first element.

  ### Parameters:

  - x element to operate on

  ### Returns:

  string string to render before first element
RenderClose (x)
  Type of function te get string for after last element.

  ### Parameters:

  - x element to operate on

  ### Returns:

  string string to render after last element
RenderPair (x, kp, vp, k, v, kstr, vstr, seqp)
  Type of function to render a key value pair.

  ### Parameters:

  - x complete table elmeent being operated on
  - kp unstringified previous pair key
  - vp unstringified previous pair value
  - k unstringified pair key to render
  - v unstringified pair value to render
  - kstr already stringified pair key to render
  - vstr already stringified pair value to render
  - seqp

    true if all keys so far have been a contiguous range of

        integers

  ### Returns:

  string stringified rendering of pair kstr and vstr
RenderSep (x, kp, vp, kn, vn, seqp)
  Type of function to render a separator between pairs.

  ### Parameters:

  - x complet table element being operated on
  - kp unstringified previous pair key
  - vp unstringified previous pair value
  - kn unstringified next pair key
  - vn unstringified next pair value
  - seqp

    true if all keys so far have been a contiguous range of

        integers

  ### Returns:

  string

  stringified rendering of separator between previous and

      next pairs

generated by LDoc 1.4.6 Last updated 2020-04-15 17:22:39