local _VERSION = 'lazybag v1.0.0' local _DESCRIPTION = 'Plain Lua tables with lazily-initialized field values.' local _COPYRIGHT = 'Copyright (C) 2011-2012 Daniele Alessandri' local lazybag = {} local mt_newindex = function(t, key, value) getmetatable(t).storage[key] = value end local mt_index = function(t, key) local mt = getmetatable(t) local storage, generators = mt.storage, mt.generators if storage[key] == nil and generators[key] ~= nil then storage[key], generators[key] = generators[key](t, key), nil end return storage[key] end local fn_lazy = function(t, key, fn) if type(fn) ~= 'function' then error('Function expected') end getmetatable(t).generators[key] = fn return fn end local fn_islazy = function(t, key) return getmetatable(t).generators[key] ~= nil end local fn_rename = function(t, old, new) local generators = getmetatable(t).generators if generators[old] ~= nil then generators[new], generators[old] = generators[old], nil elseif t[old] ~= nil then t[new], t[old] = t[old], nil end end local fn_getraw = function(t, key) local mt = getmetatable(t) return mt.generators[key] or mt.storage[key] end lazybag.new = function(other) if other == lazybag then error('Cannot initialize a lazybag container with lazybag itself') end local t = { lazy = fn_lazy, islazy = fn_islazy, rename = fn_rename, getraw = fn_getraw, } if other ~= nil then for k, v in pairs(other) do if t[k] == nil then t[k] = v end end end local mt = { generators = {}, storage = {}, __index = mt_index, __newindex = mt_newindex, } return setmetatable(t, mt) end return lazybag