|  | ||
| 
 | 
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 = {}local function loader(name, modpath)
for k,v in pairs(package.loaded._G) do
lua_libs[k] = v
end
local mod, env = {}, {}
env.module = function (name)
mod._NAME = namereturn env
setmetatable(env, { __index = function(t,k) return rawget(mod, k)
or rawget(lua_libs, k) end, __newindex = mod })
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-------- end loader5.lua
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
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().