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
levelargument behaves just like the coreerror+ function. + + +Parameters:
+-
+
- name + string + function to callout in error message + +
- i + int + argument number + +
- extramsg
+ string
+
+
additional text to append to message inside
+
+ + (optional) +parentheses +
+ - 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 +
__callmetamethod). + + +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)+ + +
+ - fn
+ function or int
+
+
- + + 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
+nilif no
+ +metamethod +Usage:
+-
+
normalize = getmetamethod(require 'std.normalize', '__call')
+ + +
+ - + + ipairs (t) + +
-
+ Iterate over elements of a sequence, until the first
nilvalue. + +Returns successive key-value pairs with integer keys starting at 1, + up to the index returned by the
+ +__lenmetamethod if any, or else + up to last non-nilvalue.Unlike Lua 5.1, any
+ +__indexmetamethod is respected.Unlike Lua 5.2+, any
__ipairsmetamethod is ignored! + + +Parameters:
+-
+
- t + table + table to iterate on + +
Returns:
+-
+
- + function + iterator function +
- + table + t the table being iterated over +
- + 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
__lenmetamethod (like Lua 5.2+), or else if there is + a__tostringmetamethod return the length of the string it + returns. Otherwise, always return one less than the lowest + integer index with anilvalue 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:
+ + +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
nset to the length. + +The returned table also has a
__lenmetamethod that returnsn, so +ipairsandunpackbehave sanely when there arenilvalued elements. + + +Parameters:
+-
+
- ... + tuple to act on + +
Returns:
+-
+
+ table
+
+
packed list of ... values, with field
+nset 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
pairsiterator, but respect__pairseven in Lua 5.1. + + +Parameters:
+-
+
- t + table + table to act on + +
Returns:
+-
+
- + function + iterator function +
- + table + t, the table being iterated over +
- + 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:
+ + +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
+ + +
+ - fn
+ function or int
+
+
- + + 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.unpackin newer-, orunpackin 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
+-
+
-
+ boolean
+
falsewhenf(...)raised an error
+ - + string + error message +
Or
+-
+
+ boolean
+
truewhenf(...)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
+-
+
+
nilotherwise +
+ - + + math.type (x) + +
-
+ Return 'integer', 'float' or
nilaccording 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
+-
+
+
nilotherwise +
+ - + + 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.pathsepdelimited template in the given path, + search for an readable file made by first substituting for sep + withpackage.dirsep, and then replacing any +package.pathmarkwith the result. The first such file, if any + is returned. + + +Parameters:
+-
+
- name + string + name of search file + +
- path
+ string
+
package.pathsepdelimited 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
+-
+
-
+
nil
+ - + 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.configsubstrings. + + +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=valuesyntax. 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
+ + (default 1) +caller's environment +
+
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
+
+ - keys
+ table
+
+
- + + 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 +
+