lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

 Hisham <> wrote:

I think that was in the right direction. Geoff Leyland and Steve
Donovan provided valuable feedback, here's an improved version:

-------- begin loader5.lua ( )
local lua_libs = {}
for k,v in pairs(package.loaded._G) do
  lua_libs[k] = v

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
 local fh = assert(, 'rb'))
 local source = fh:read'*a'
 local ret = assert(load(source, modpath, 'bt', env))(name)
 return ret or mod

-- replace Lua loader
package.searchers[2] = function (name)
 local modpath, msg = package.searchpath(name, package.path)
 if modpath then
   return loader, modpath
   return nil, msg
-------- 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().

I tried this out.  I like it.  A lot.  It seems quite clear and simple to use.  Are there any other downsides?