Module:require when needed
Jump to navigation
Jump to search
- The following documentation is located at Module:require when needed/documentation. [edit]
- Useful links: subpage list • links • transclusions • testcases • sandbox
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 setmetatable = setmetatable
local tostring = tostring
local unpack = unpack
local function get_nested(a, b, ...)
if not a then
return nil
elseif ... then
return get_nested(a[b], ...)
end
return a[b]
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)
return (mt[0] or get_obj(mt))(...)
end
local function __index(self, k)
local mt = getmetatable(self)
return (mt[0] or get_obj(mt))[k]
end
local function __ipairs(self)
local mt = getmetatable(self)
return ipairs(mt[0] or get_obj(mt))
end
local function __newindex(self, k, v)
local mt = getmetatable(self)
local t = mt[0] or get_obj(mt)
t[k] = v
end
local function __pairs(self)
local mt = getmetatable(self)
return pairs(mt[0] or get_obj(mt))
end
local function __tostring(self)
local mt = getmetatable(self)
return tostring(mt[0] or get_obj(mt))
end
return function(modname, ...)
local obj = loaded[modname]
if not obj then
return setmetatable({}, {
modname,
__call = __call,
__index = __index,
__ipairs = __ipairs,
__newindex = __newindex,
__pairs = __pairs,
__tostring = __tostring,
...
})
elseif ... then
return get_nested(obj, ...)
end
return obj
end