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.
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.
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.)
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With