lua-users home
lua-l archive

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


On 19/10/2011, at 8:09 PM, Hisham wrote:

> Take 2, then: I believe the following addresses this issue, and I couldn't spot any side effects.
> 
> -------- begin loader.lua
> -- clone _G so that globals from the program don't invade the module
> 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 = {}, {}
>  setmetatable(mod, { __index = function(t,k) return rawget(env, k) end })
>  setmetatable(env, { __index = function(t,k) return rawget(mod, k) or
> rawget(lua_libs, k) end, __newindex = mod })
>  env.module = function (name)
>    env._NAME = name
>    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 loader.lua
> 
> Again, feedback on these design proposals for module() are welcome.


That looks like it's on the right track.

What's the setmetatable(mod, { __index = function(t,k) return rawget(env, k) end }) for?  It doesn't look like env can ever get any members so why bother looking in it?

If that's the case, then you probably need to set the env.module function before you set env's metatable.  (but it's ok that env._NAME actually gets set in mod)

Does anyone have any insight into the overhead of a couple of closures per module and looking up modules fields through yet another __index?