I think that was in the right direction. Geoff Leyland and Steve
Donovan provided valuable feedback, here's an improved version:
-------- begin loader5.lua ( https://gist.github.com/1298652 )
local lua_libs = {}
for k,v in pairs(package.loaded._G) do
lua_libs[k] = v
end
local function loader(name, modpath)
local mod, env = {}, {}
env.module = function (name)
mod._NAME = name
setmetatable(env, { __index = function(t,k) return rawget(mod, k)
or rawget(lua_libs, k) end, __newindex = mod })
return env
end
local fh = assert(io.open(modpath, 'rb'))
local source = fh:read'*a'
fh:close()
local ret = assert(load(source, modpath, 'bt', env))(name)
return ret or mod
end
-- replace Lua loader
package.searchers[2] = function (name)
local modpath, msg = package.searchpath(name, package.path)
if modpath then
return loader, modpath
else
return nil, msg
end
end
-------- end loader5.lua
In this version, module definitions are not frozen (as per Geoff
Leyland's concern) and no environment overhead is added to modules
that choose not to use module() (as per Steve Donovan's concern).
It may be more complex/magic than the Lua 5.1 implementation of
module() (is this revision as well?), but it does what we all wanted
module() to do (declare a module and allow declaration of public and
private entries through the environment), while giving users
convenience equivalent to that people use package.seeall (another
popular construct) for, without the widely discussed drawbacks of Lua
5.1 module().