lua-users home
lua-l archive

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


On Wed, Oct 9, 2013 at 3:02 AM, Tom N Harris <telliamed@whoopdedo.org> wrote:
> The module function is mutating the first upvalue of the calling function
> without regard to whether it is the _ENV table.

The 5.2 compat module is indeed too simplistic - I found this out when
trying to pack multiple modules into a single Lua file.

Building module() on this would work properly, subject to Roberto's
caveat - note that it isn't a cheap operation!

    -- setfenv/getfenv replacements for Lua 5.2
    -- by Sergey Rozhenko
    -- http://lua-users.org/lists/lua-l/2010-06/msg00313.html
    -- Roberto Ierusalimschy notes that it is possible for getfenv to return nil
    -- in the case of a function with no globals:
    -- http://lua-users.org/lists/lua-l/2010-06/msg00315.html
    function compat.setfenv(f, t)
        f = (type(f) == 'function' and f or debug.getinfo(f + 1, 'f').func)
        local name
        local up = 0
        repeat
            up = up + 1
            name = debug.getupvalue(f, up)
        until name == '_ENV' or name == nil
        if name then
            debug.upvaluejoin(f, up, function() return name end, 1) --
use unique upvalue
            debug.setupvalue(f, up, t)
        end
        if f ~= 0 then return f end
    end

    function compat.getfenv(f)
        local f = f or 0
        f = (type(f) == 'function' and f or debug.getinfo(f + 1, 'f').func)
        local name, val
        local up = 0
        repeat
            up = up + 1
            name, val = debug.getupvalue(f, up)
        until name == '_ENV' or name == nil
        return val
    end
end

(This is from Penlight's pl.compat module; these guys are exported by
pl.utils as utils.(get|set)fenv)

It's an academic point personally, because I've been a happy non-user
of module() for years.  But I will say that converting codebases that
use module() is an error-prone process unless you use a static
analysizer