lua-users home
lua-l archive

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


On Wed, Oct 19, 2011 at 4:04 AM, Geoff Leyland
<geoff_leyland@fastmail.fm> wrote:
> On 19/10/2011, at 6:25 PM, Hisham wrote:
>
>> In terms of "fixing module()", I think Fabio's implementation is right
>> on the money:
>>
>> http://article.gmane.org/gmane.comp.lang.lua.general/84283
>>
>> It shows that a sane implementation of module() can be done with
>> standard Lua mechanisms. Do any of the anti-module proponents see any
>> problems with that design?
>
> Would taking a shallow copy of the module to hide _G would make
>
> -- mod.lua
> module("mod")
> count = 1
> function increment() count = count + 1; print(count) end
>
>
> -- main.lua
> local mod = require("mod")
> print(mod.count)
> mod.increment()
> print(mod.count)
>
>
> print "1 2 1" rather than "1 2 2"?

Good point. Fabio mentioned that it would "freeze" global definitions
and your example shows how that can be a problem. 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.

-- Hisham
http://hisham.hm/ - http://luarocks.org/