Module utils.magic

Meta-programming utilities.

Functions

enable_table_gc(t) Make __gc for tables work for old Lua engines too.
memoize(f) Caches the results of a function call.
once([lock_name,] fn) Protects a function against being called recursively.
setup_autoload(t) Enables autoloading for missing variables.
setup_strict(t, protect_read, protect_write) Protects a namespace against referencing missing variables.
vbfy(meta) Enables “syntactic sugar” for properties.
vbfy_singleton(module) Enables “syntactic sugar” for properties, on modules.


Functions

enable_table_gc(t)

Make __gc for tables work for old Lua engines too.

Lua 5.2+ supports __gc for table. Older Lua engines don’t. To make older Lua engines support it, add a call to enable_table_gc:

Let’s first look at a Lua 5.2+ compatible code:

do
  local t = setmetatable({},{
    __gc = function() print("works") end
  })
end
collectgarbage()

To make it work under older Lua engines (Lua 5.1 and LuaJIT), do:

do
  local t = setmetatable({},{
    __gc = function() print("works") end
  })
  utils.magic.enable_table_gc(t)
end
collectgarbage()
memoize(f)
Caches the results of a function call.

local function heavy(x)
  return x^(1/3)
end

local light = utils.magic.memoize(heavy)

-- The following calculates the result just once.
print(light(27), light(27), light(27))

The memoized function may receive several arguments, but as the caching key will serve only the first argument. Thus light(3, 5) and light(3, "whatever") will give the same result.

once([lock_name,] fn)
Protects a function against being called recursively.

It wraps the function fn inside a function that uses locking to ensure that the function is invoked only once in the calling stack.

See example at <<load>>.

setup_autoload(t)
Enables autoloading for missing variables.

You then use autoload() to describe how to load the missing values.

local t = {
  one = 1,
  two = 2,
}

utils.magic.setup_autoload(t)

print(t.m)         -- prints 'nil'

-- Autoload a module:

t.autoload('m', 'math')

print(t.m.cos(0))  -- ok

-- Autoload a function (of a module):

t.autoload('cosine', { 'math', 'cos' })

print(t.cosine(0)) -- ok

-- Autoload a custom value:

t.autoload('banner', function()
  return fs.read('/etc/issue', '*l')
end)

print(t.banner)    -- ok

This function returns the magic module itself, and ‘autoload()’ returns the table itself, thereby allowing for “fluent API”:

setup_strict(t, protect_read, protect_write)
Protects a namespace against referencing missing variables.

The user may then use declare() to allow referencing certain missing variables.

local t = {
  one = 1,
  two = 2,
}

utils.magic.setup_strict(t, true, true)

print(t.one)    -- ok

print(t.three)  -- raises exception!
t.three = 3     -- raises exception!

t.declare('three')

print(t.three)  -- ok
t.three = 3     -- ok

This facility is how the global namespace is protected. See setup_strict(_G, true, true) in core/_bootstrap.lua.

This facility is how constants in the fs module are protected against misspellings. E.g., doing fs.O_RWDR instead of fs.O_RDWR raises an exception.

This function returns the magic module itself, thereby allowing for “fluent API”.

vbfy(meta)
Enables “syntactic sugar” for properties.

This facility lets you type (for example):

obj.title = "abc"
print(obj.title)

instead of:

obj:set_title("abc")
print(obj:get_title())

An attempt to read/write a property that don’t have a getter/setter will be regarded as a typo and an exception will be raised:

obj.undeclared_property = -666  -- raises exception!

To allow access to fields without writing getters/setters for them, you need to declare them in the __allowed_properties table. Alternatively, use rawget/rawset to access such fields.

The “vb” in the name of this function stands for “Visual Basic”. Since it’s a trademark, this function will be renamed as soon as somebody stimulates his neurons enough to come up with a better name.

This facility is used for widgets. We don’t want to encourage its use outside that realm because it’s not very conventional. Therefore we don’t provide a usage example here (but see tests/auto/magic_vbfy.mcs if you want to).

Parameters:

  • meta The meta table.
vbfy_singleton(module)
Enables “syntactic sugar” for properties, on modules.

Like vbfy but works on modules (on tables, to be exact).

generated by LDoc 1.4.3 Last updated 2016-08-23 17:29:40