Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lua: setfenv() vs. _ENV

Tags:

lua

What is the big deal with Lua switching from setfenv() to _ENV?

In various "What's New" sources, this move is mentioned as one of the most important changes between Lua versions 5.1 and 5.2.

However, the examples given in PIL and elsewhere can be trimmed to the following:

-- Lua 5.1                   -- Lua 5.2
function myfunc()            function myfunc()
    setfenv(1, {})               _ENV = {}
end                          end

So far, what we gained here is we have saved five key strokes. (I believe the situation is not much different from the C side.) Moreover, if I got it right, setfenv() can be used both from the outside and from the inside of a function, whereas _ENV can be accessed only from the inside of a function. (Of course, when using the C API, one can access the upvalues directly.) From what I wrote, the 5.2 approach seems much less flexible.

In his The Novelties of Lua 5.2, Roberto writes:

"Being a syntactic sugar, it is much simpler than the old environments"

Where's the simplicity? What have I overlooked?

I believe this topic is worth better treatment that it is given in the 5.2 User Manual.

like image 871
peter.slizik Avatar asked Aug 18 '12 19:08

peter.slizik


People also ask

What does setfenv do?

Sets the environment to be used by the given function. f can be a Lua function or a number that specifies the function at that stack level: Level 1 is the function calling setfenv . setfenv returns the given function.

What is an environment in Lua?

Lua keeps all its global variables in a regular table, called the environment. ( To be more precise, Lua keeps its "global" variables in several environments, but we will ignore this multiplicity for a while.)


1 Answers

Where's the simplicity?

It depends on how you define "simplicity".

In Lua 5.1, the environment was a magical, mystical setting that was unlike any other setting in the system. It didn't have an explicit place and it could only be set by using standard library features.

In Lua 5.2, the environment is a variable, just like any other. It has a name which you can use. So it's simpler in that it's more obvious what's going on.

Furthermore, in Lua 5.1, the environment of a function can be changed dynamically.

In Lua 5.2, outside of direct upvalue manipulation, once a function has an environment, that is the environment it will have in perpetuity. The environment for a function is inherited, being lexically scoped like a regular local variable. So if you look at your code, you can easily see what environment a function is in. If there is no local _ENV in the scope of that function's creation, then the environment shall be the environment of the chunk (which is defined by the load call).

like image 74
Nicol Bolas Avatar answered Sep 26 '22 04:09

Nicol Bolas