Lubyk base module
This module contains core functions (code loading, templates, helpers).
MIT license © Gaspard Bucher 2014.
Installation
With luarocks:
$ luarocks install lub
Dependencies
.VERSION = '1.1.0'
Current version respecting semantic versioning.
.DEPENDS = {
"lua >= 5.1, < 5.4"
Compatible with Lua 5.1 to 5.3 and LuaJIT
"luafilesystem >= 1.4.0"
Uses Lua Filesystem
}
.DESCRIPTION = {
Basic description for luarocks.
.BUILD = {
Build settings for lut.Builder
Environment information
.plat ()
Get name of currently running platform. Values are 'linux', 'macosx', 'unix' and 'win32'. Returns "platform", "platform detail", "system"
Platform detail is MinGW or Cygwin for example.
Class management
.class (class_name, tbl)
Declare a new class with the following conventions:
- The
.type
field contains the full class name. - The returned table is the metatable for all instances of this class and contains the functions.
- Calling the table with
foo.Bar()
is an alias for a call tofoo.Bar.new
.
Usage:
local lub = require 'lub' local lut = require 'lut' local lib = lub.class 'lut.Doc' -- ... return lib
WARN When using an initial lua table, make sure to use parenthesis around the function call:
local lib = lub.class('lut.Doc', { is_cool = true, })
Algorithm
.search (data, func, max_depth)
Search a tree using lua function for node testing or collecting. This method is an alias for BFS.
Optional argument max_depth
is to avoid hanging in case the data contains loops. The default value for max_depth
is 3000.
If the function func
used for testing returns any value different from false or nil, the search is terminated and this value is returned.
Example to find an element in an xml tree:
local poor_guy = lub.search(data, function(node) if node.xml == 'Person' and node.status == 'poor' then return node end end)
Example to collect elements:
local list = {} lub.search(data, function(node) if node.xml == 'Person' then table.insert(list, node) end end
Speed
The traversal speed depends on whether we are using Lua or LuaJIT. The tests below were done on a relatively large medical XML file without very deep nesting.
===== Lua IDDFS 5.10 BFS 2.58 ===== LuaJIT IDDFS 0.30 BFS 0.36
.IDDFS (data, func, max_depth)
Iterative deepening depth-first search with max depth testing. See search for usage.
.BFS (data, func, max_depth)
Breath-first search with max depth testing. See search for usage.
Filesystem
.path (path, level)
Return a path by resolving special initial characters. The level
argument can move further up the call hierarchy before resolving paths (use 1
to move up one call). Special initial characters are:
/ | absolute path, resolves '..' in path. |
| | path relative to script directory, resolves '..' in path. |
& | returns current script path. |
For example:
print(lub.path '|') --> current script directory print(lub.path '|..') --> parent of script directory
.fileType (path)
Test for file/directory existence at path
. If the element exists, returns the file type such as 'directory' or 'file'. Returns nil if there is nothing at the given path.
.exist (path)
Return true if the file or folder pointed by path
exists.
.content (basepath, path)
Return the content of a file as a lua string (not suitable for very long content where parsing the file chunks by chunks is better). The method accepts either a single path
argument or a basepath
and relative path
.
.writeall (filepath, data, check_diff)
Write data
to filepath
, creating path folders if necessary. If check_diff
is true, only write if the content has changed to avoid changing stat information on the file.
.makePath (path)
Build necessary folders to create a given path
.
.move (path, new_path)
Move a file or directory from path
to new_path
. This is like "os.rename" but it also builds necessary path components in new_path.
.copy (path, new_path)
Copy a file from path
to new_path
. Builds necessary path components in new_path.
.rmFile (path)
Delete the file located at path
. Does nothing if the element at path
does not exist (already removed).
.rmTree (path, recursive)
Remove the directory at path
. If recursive
is true, remove recursively. This is a dangerous method if the source path is not ensured to be exempt of mistakes.
.dir (filepath)
Return the parent folder and filename from a filepath
. Usage:
local base, file = lub.dir(filepath)
This can also be used on urls.
.absolutizePath (path, basepath)
Return an absolute path from a path
and optional basepath
. If basepath is not provided, the method uses the current directory. This method resolves /../
and /./
in paths and returns a clean path. Can also be used with urls.
For example:
local abs_path = lub.absolutizePath('foo/bar/../baz', '/home') --> '/home/foo/baz'
.absToRel (abs_string, base)
Transform an absolute path or url to a relative path with given base. For example:
local rel = lub.absToRel('/home/foo/bar', '/home/foo/baz') --> '/home/foo/bar' local rel = lub.absToRel('/home/foo/bar', '/home/foo') --> 'bar'
Strings, Arrays
.strip (str)
Removes white spaces at the beginning and end of the string str
.
.split (str, pat)
Split a string str
into elements separated by the pattern pat
. The function returns a table.
local t = lub.split('foo/bar/baz', '/') --> {'foo', 'bar', 'baz'}
.join (list, sep)
Join elements of a table list
with separator sep
. Returns a string.
local x = lub.join({'foo', 'bar', 'baz'}, '.') --> 'foo.bar.baz'
.keys (dict, no_order)
Get the ordered list of string keys from a table. If no_order
is true, keys are not sorted.
.insertSorted (list, elem, key)
Insert elem
into a list
, keeping entries in "list" sorted. If elem is not a string, the elem[key]
is used to get a string for sorting.
.merge (source, table)
Merge values in table
inside source
. All keys are considered (array and hash).
.deepMerge (base, key, value)
Deep merge value
into base
at key
. Returns true if base has been changed. For example:
local base = {a = { b = 4, c = 5 }} lub.deepMerge(base, 'a', { c = 5 }) --> false (nothing changed) lub.deepMerge(base, 'a', { c = 6 }) --> true, base = {a = { b = 4, c = 6 }}
Debugging
.traceRequire (enable)
Print calls to require
. This can be used to list all code dependencies. Usage:
lub.traceRequire(true) -- From now on, all require statements are printed.
If you simply want to make sure no require
is called to autoload code after some point, you should use Autoload.strict.
.log (...)
Print a log message with the current file name and line. This is better then using "print" because it gives us some information on the context of the print statement.
lub.log('foo') --> lub/util.lua:426: foo
Miscellanous
.deprecation (lib_name, old, new, ...)
Declare a method as being deprecated. This should be used when method names are changed to avoid breaking code without warnings. The syntax is:
function lib.badName(...) return lib.deprecation('lub', 'badName', 'betterName', ...) end
When someone uses the "badName" method, a deprecation warning is printed:
[DEPRECATION] {traceback} 'lub.badName' is deprecated. Please use 'lub.betterName' instead.
.shellQuote (str)
Quote string str
so that it can be inserted in a shell command. Example:
os.execute(string.format('latex %s', lub.shellQuote(filepath)))
Classes
Autoload
This class creates a module table that will automatically call require to find new keys. This enables "load as needed" code. If the required code cannot be found, generates an error.
Dir
This is a helper to access/glob directory trees. It requires 'lfs' (lua filesystem).
Param
This class acts as a proxy around lua tables allowing paramter save and recall.
Template
Simplistic templating system inspired by Zed A. Shaw's minimal template for Tir.