lua-users home
lua-l archive

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




2010/5/20 François Perrad <francois.perrad@gadz.org>


2010/5/20 Roberto Ierusalimschy <roberto@inf.puc-rio.br>

> With Lua 5.1, I have the following code :
>
>     setfenv(level, M)
>
> With Lua 5.2.0 work2, I rewrite it as following (compatible with Lua 5.1) :
>
>     debug.setfenv(debug.getinfo(level, 'f').func, M)
>
> Now, with Lua 5.2.0 work3, it becomes :
>
>     if debug.setupvalue(debug.getinfo(level, 'f').func, 1, M) ~= '_ENV' then
>         setfenv(level, M) -- Lua 5.1
>     end
>
> The value 1 seems magical, but I think _ENV is alway the first upvalue.

Not necessarily. If the function is a main function (that is, the direct
result of load) then _ENV is always the first (and only) upvalue and it
is always present. Other functions have _ENV just like any other upvalue.
For instance, consider the following code:

 local a
 function foo ()
   return a + b
 end

In function foo, the first upvalue is 'a' and the second is '_ENV'.


Thanks for this information.
I'll write a more robust code.

I rewrite setfenv as follow :

local function setfenv (level, M)
    level = level + 1
    local func = debug.getinfo(level, 'f').func
    local up = 1
    while true do
        local name = debug.getupvalue(func, up)
        if name == '_ENV' then
            debug.setupvalue(func, up, M)
            return
        end
        if name == nil then
            break
        end
        up = up + 1
    end
    _G.setfenv(level, M) -- Lua 5.1
end

François
 

François
 
-- Roberto