lubyk logo

Lubyk documentation

Lubyk base module Build Status

This module contains core functions (code loading, templates, helpers).

Fork me on GitHub

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 to foo.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.