Skip to content

Instantly share code, notes, and snippets.

@pygy
Last active August 29, 2015 14:02
Embed
What would you like to do?
--- usage:
-- require = require"require".require
-- :o)
local error, ipairs, type = error, ipairs, type
local t_concat = table.concat
--- Helpers
local function _tostring(s) return ""..s end
local function checkstring(s)
local success, res = pcall(_tostring, s)
if success then return res end
error("bad argument #1 to 'require' (string expected, got "..type(s)..")", 3)
end
local function callable(f)
if type(f) == "function" then return true end
local mt = getmetatable(f) or false
return mt and type(mt.__call) == "function"
end
--- for Lua 5.1
local package, p_loaded = package, package.loaded
local sentinel = {}
-- sentinel = function()end
local function require51 (name)
name = checkstring(name)
print ("sentinel", sentinel, p_loaded[name])
if p_loaded[name] == sentinel then
error("loop or previous error loading module '"..name.."'", 2)
elseif not p_loaded[name] then
local msg = {}
local loader
for _, searcher in ipairs(package.loaders) do
loader = searcher(name)
if callable(loader) then break end
if type(loader) == "string" then
-- `loader` is actually an error message
msg[#msg + 1] = loader
end
loader = nil
end
if loader == nil then
error("module '" .. name .. "' not found: "..t_concat(msg), 2)
end
p_loaded[name] = sentinel
print("before load", sentinel)
local res = loader(name)
print("res", res)
if res ~= nil then
p_loaded[name] = res
else
p_loaded[name] = true
end
print("after load", sentinel)
end
return p_loaded[name]
end
--- for Lua 5.2
local function require52 (name)
name = checkstring(name)
if not p_loaded[name] then
local msg = {}
local loader, param
for _, searcher in ipairs(package.searchers) do
loader, param = searcher(name)
if callable(loader) then break end
if type(loader) == "string" then
-- `loader` is actually an error message
msg[#msg + 1] = loader
end
loader = nil
end
if loader == nil then
error("module '" .. name .. "' not found: "..table.concat(msg), 2)
end
local res = loader(name, param)
if res ~= nil then
p_loaded[name] = res
else
p_loaded[name] = true
end
end
return p_loaded[name]
end
local module = {require51 = require51, require52 = require52}
if _VERSION == "Lua 5.1" then module.require = require51 end
if _VERSION == "Lua 5.2" then module.require = require52 end
--- rerequire :o)
for _, o in ipairs{
{"rerequiredefault", require},
{"rerequire", module.require},
{"rerequire51", require51},
{"rerequire52", require52}
} do
local rereq, req = o[1], o[2]
module[rereq] = function(name)
p_loaded[name] = nil
return req(name)
end
end
return module
@SoniEx2
Copy link

SoniEx2 commented Jun 25, 2014

On line #23 you should use debug.getmetatable (if available) because of __metatable...

@pygy
Copy link
Author

pygy commented Jun 25, 2014

indeed, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment