Jump to content

Module:require when needed

From Wiktionary, the free dictionary

A helper function which can be used in place of require if it's not certain that the module in question will be needed. If the module has already been loaded, then it is simply returned; if it hasn't, then it won't be loaded until it is first used.

This is generally useful when defining variables at the start of a module.

local getmetatable = getmetatable local ipairs = ipairs local loaded = package.loaded local pairs = pairs local require = require local select = select local setmetatable = setmetatable local tostring = tostring local unpack = unpack or table.unpack -- Lua 5.2 compatibility  local function get_nested(obj, ...) local n = select("#", ...) if n == 0 then return obj end obj = obj[...] for i = 2, n do obj = obj[select(i, ...)] end return obj end  local function get_obj(mt) local obj = require(mt[1]) if #mt > 1 then obj = get_nested(obj, unpack(mt, 2)) end mt[0] = obj return obj end  local function __call(self, ...) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return obj(...) end  local function __index(self, k) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return obj[k] end  local function __ipairs(self) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return ipairs(obj) end  local function __newindex(self, k, v) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end obj[k] = v end  local function __pairs(self) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return pairs(obj) end  local function __tostring(self) local mt = getmetatable(self) local obj = mt[0] if obj == nil then obj = get_obj(mt) end return tostring(obj) end  return function(modname, ...) local mod = loaded[modname] if mod ~= nil then return get_nested(mod, ...) end return setmetatable({}, { modname, __call = __call, __index = __index, __ipairs = __ipairs, __newindex = __newindex, __pairs = __pairs, __tostring = __tostring, -- TODO: other metamethods, if needed. ... }) end