1--[[-- 2 Lua Standard Libraries. 3 4 This module contains a selection of improved Lua core functions, among 5 others. 6 7 Also, after requiring this module, simply referencing symbols in the 8 submodule hierarchy will load the necessary modules on demand. 9 10 By default there are no changes to any global symbols, or monkey 11 patching of core module tables and metatables. However, sometimes it's 12 still convenient to do that: For example, when using stdlib from the 13 REPL, or in a prototype where you want to throw caution to the wind and 14 compatibility with other modules be damned. In that case, you can give 15 `stdlib` permission to scribble all over your namespaces by using the 16 various `monkey_patch` calls in the library. 17 18 @todo Write a style guide (indenting/wrapping, capitalisation, 19 function and variable names); library functions should call 20 error, not die; OO vs non-OO (a thorny problem). 21 @todo pre-compile. 22 @module std 23]] 24 25 26local base = require "std.base" 27 28local M, monkeys 29 30 31local function monkey_patch (namespace) 32 base.copy (namespace or _G, monkeys) 33 return M 34end 35 36 37local function barrel (namespace) 38 namespace = namespace or _G 39 40 -- Older releases installed the following into _G by default. 41 for _, name in pairs { 42 "functional.bind", "functional.collect", "functional.compose", 43 "functional.curry", "functional.filter", "functional.id", 44 "functional.map", 45 46 "io.die", "io.warn", 47 48 "string.pickle", "string.prettytostring", "string.render", 49 50 "table.pack", 51 52 "tree.ileaves", "tree.inodes", "tree.leaves", "tree.nodes", 53 } do 54 local module, method = name:match "^(.*)%.(.-)$" 55 namespace[method] = M[module][method] 56 end 57 58 -- Support old api names, for backwards compatibility. 59 namespace.fold = M.functional.fold 60 namespace.metamethod = M.getmetamethod 61 namespace.op = M.operator 62 namespace.require_version = M.require 63 64 require "std.io".monkey_patch (namespace) 65 require "std.math".monkey_patch (namespace) 66 require "std.string".monkey_patch (namespace) 67 require "std.table".monkey_patch (namespace) 68 69 return monkey_patch (namespace) 70end 71 72 73 74--- Module table. 75-- 76-- In addition to the functions documented on this page, and a `version` 77-- field, references to other submodule functions will be loaded on 78-- demand. 79-- @table std 80-- @field version release version string 81 82local function X (decl, fn) 83 return require "std.debug".argscheck ("std." .. decl, fn) 84end 85 86M = { 87 --- Enhance core `assert` to also allow formatted arguments. 88 -- @function assert 89 -- @param expect expression, expected to be *truthy* 90 -- @string[opt=""] f format string 91 -- @param[opt] ... arguments to format 92 -- @return value of *expect*, if *truthy* 93 -- @usage 94 -- std.assert (expected ~= nil, "100% unexpected!") 95 -- std.assert (expected ~= nil, "%s unexpected!", expected) 96 assert = X ("assert (?any, ?string, [any...])", base.assert), 97 98 --- A [barrel of monkey_patches](http://dictionary.reference.com/browse/barrel+of+monkeys). 99 -- 100 -- Apply **all** `monkey_patch` functions. Additionally, for backwards 101 -- compatibility only, write a selection of sub-module functions into 102 -- the given namespace. 103 -- @function barrel 104 -- @tparam[opt=_G] table namespace where to install global functions 105 -- @treturn table module table 106 -- @usage local std = require "std".barrel () 107 barrel = X ("barrel (?table)", barrel), 108 109 --- An iterator over all elements of a sequence. 110 -- If *t* has a `__pairs` metamethod, use that to iterate. 111 -- @function elems 112 -- @tparam table t a table 113 -- @treturn function iterator function 114 -- @treturn table *t*, the table being iterated over 115 -- @return *key*, the previous iteration key 116 -- @see ielems 117 -- @see pairs 118 -- @usage 119 -- for value in std.elems {a = 1, b = 2, c = 5} do process (value) end 120 elems = X ("elems (table)", base.elems), 121 122 --- Evaluate a string as Lua code. 123 -- @function eval 124 -- @string s string of Lua code 125 -- @return result of evaluating `s` 126 -- @usage std.eval "math.min (2, 10)" 127 eval = X ("eval (string)", base.eval), 128 129 --- An iterator over the integer keyed elements of a sequence. 130 -- If *t* has a `__len` metamethod, iterate up to the index it returns. 131 -- @function ielems 132 -- @tparam table t a table 133 -- @treturn function iterator function 134 -- @treturn table *t*, the table being iterated over 135 -- @treturn int *index*, the previous iteration index 136 -- @see elems 137 -- @see ipairs 138 -- @usage 139 -- for v in std.ielems {"a", "b", "c"} do process (v) end 140 ielems = X ("ielems (table)", base.ielems), 141 142 --- An iterator over elements of a sequence, until the first `nil` value. 143 -- 144 -- Like Lua 5.1 and 5.3, but unlike Lua 5.2 (which looks for and uses the 145 -- `__ipairs` metamethod), this iterator returns successive key-value 146 -- pairs with integer keys starting at 1, up to the first `nil` valued 147 -- pair. 148 -- @function ipairs 149 -- @tparam table t a table 150 -- @treturn function iterator function 151 -- @treturn table *t*, the table being iterated over 152 -- @treturn int *index*, the previous iteration index 153 -- @see ielems 154 -- @see npairs 155 -- @see pairs 156 -- @usage 157 -- -- length of sequence 158 -- args = {"first", "second", nil, "last"} 159 -- --> 1=first 160 -- --> 2=second 161 -- for i, v in std.ipairs (args) do 162 -- print (string.format ("%d=%s", i, v)) 163 -- end 164 ipairs = X ("ipairs (table)", base.ipairs), 165 166 --- Return a new table with element order reversed. 167 -- Apart from the order of the elments returned, this function follows 168 -- the same rules as @{ipairs} for determining first and last elements. 169 -- @function ireverse 170 -- @tparam table t a table 171 -- @treturn table a new table with integer keyed elements in reverse 172 -- order with respect to *t* 173 -- @see ielems 174 -- @see ipairs 175 -- @usage 176 -- local rielems = std.functional.compose (std.ireverse, std.ielems) 177 -- for e in rielems (l) do process (e) end 178 ireverse = X ("ireverse (table)", base.ireverse), 179 180 --- Return named metamethod, if any, otherwise `nil`. 181 -- @function getmetamethod 182 -- @param x item to act on 183 -- @string n name of metamethod to lookup 184 -- @treturn function|nil metamethod function, or `nil` if no metamethod 185 -- @usage lookup = std.getmetamethod (require "std.object", "__index") 186 getmetamethod = X ("getmetamethod (?any, string)", base.getmetamethod), 187 188 --- Overwrite core methods and metamethods with `std` enhanced versions. 189 -- 190 -- Write all functions from this module, except `std.barrel` and 191 -- `std.monkey_patch`, into the given namespace. 192 -- @function monkey_patch 193 -- @tparam[opt=_G] table namespace where to install global functions 194 -- @treturn table the module table 195 -- @usage local std = require "std".monkey_patch () 196 monkey_patch = X ("monkey_patch (?table)", monkey_patch), 197 198 --- Ordered iterator for integer keyed values. 199 -- Like ipairs, but does not stop until the largest integer key. 200 -- @function npairs 201 -- @tparam table t a table 202 -- @treturn function iterator function 203 -- @treturn table t 204 -- @see ipairs 205 -- @see rnpairs 206 -- @usage 207 -- for i,v in npairs {"one", nil, "three"} do ... end 208 npairs = X ("npairs (table)", base.npairs), 209 210 --- Enhance core `pairs` to respect `__pairs` even in Lua 5.1. 211 -- @function pairs 212 -- @tparam table t a table 213 -- @treturn function iterator function 214 -- @treturn table *t*, the table being iterated over 215 -- @return *key*, the previous iteration key 216 -- @see elems 217 -- @see ipairs 218 -- @usage 219 -- for k, v in pairs {"a", b = "c", foo = 42} do process (k, v) end 220 pairs = X ("pairs (table)", base.pairs), 221 222 --- Enhance core `require` to assert version number compatibility. 223 -- By default match against the last substring of (dot-delimited) 224 -- digits in the module version string. 225 -- @function require 226 -- @string module module to require 227 -- @string[opt] min lowest acceptable version 228 -- @string[opt] too_big lowest version that is too big 229 -- @string[opt] pattern to match version in `module.version` or 230 -- `module._VERSION` (default: `"([%.%d]+)%D*$"`) 231 -- @usage 232 -- -- posix.version == "posix library for Lua 5.2 / 32" 233 -- posix = require ("posix", "29") 234 require = X ("require (string, ?string, ?string, ?string)", base.require), 235 236 --- An iterator like ipairs, but in reverse. 237 -- Apart from the order of the elments returned, this function follows 238 -- the same rules as @{ipairs} for determining first and last elements. 239 -- @function ripairs 240 -- @tparam table t any table 241 -- @treturn function iterator function 242 -- @treturn table *t* 243 -- @treturn number `#t + 1` 244 -- @see ipairs 245 -- @see rnpairs 246 -- @usage for i, v = ripairs (t) do ... end 247 ripairs = X ("ripairs (table)", base.ripairs), 248 249 --- An iterator like npairs, but in reverse. 250 -- Apart from the order of the elments returned, this function follows 251 -- the same rules as @{npairs} for determining first and last elements. 252 -- @function rnpairs 253 -- @tparam table t a table 254 -- @treturn function iterator function 255 -- @treturn table t 256 -- @see npairs 257 -- @see ripairs 258 -- @usage 259 -- for i,v in rnpairs {"one", nil, "three"} do ... end 260 rnpairs = X ("rnpairs (table)", base.rnpairs), 261 262 --- Enhance core `tostring` to render table contents as a string. 263 -- @function tostring 264 -- @param x object to convert to string 265 -- @treturn string compact string rendering of *x* 266 -- @usage 267 -- -- {1=baz,foo=bar} 268 -- print (std.tostring {foo="bar","baz"}) 269 tostring = X ("tostring (?any)", base.tostring), 270 271 version = "General Lua libraries / @VERSION@", 272} 273 274 275monkeys = base.copy ({}, M) 276 277-- Don't monkey_patch these apis into _G! 278for _, api in ipairs {"barrel", "monkey_patch", "version"} do 279 monkeys[api] = nil 280end 281 282 283--- Metamethods 284-- @section Metamethods 285 286return setmetatable (M, { 287 --- Lazy loading of stdlib modules. 288 -- Don't load everything on initial startup, wait until first attempt 289 -- to access a submodule, and then load it on demand. 290 -- @function __index 291 -- @string name submodule name 292 -- @treturn table|nil the submodule that was loaded to satisfy the missing 293 -- `name`, otherwise `nil` if nothing was found 294 -- @usage 295 -- local std = require "std" 296 -- local prototype = std.object.prototype 297 __index = function (self, name) 298 local ok, t = pcall (require, "std." .. name) 299 if ok then 300 rawset (self, name, t) 301 return t 302 end 303 end, 304}) 305