• Announcement: Lua.org now officially recommends this forum as a meeting place for the Lua community

How works _G and _ENV and what can I do with them? (1 Viewer)

Herly Quijano

Newcomer
Joined
Mar 19, 2021
Messages
70
Reaction score
7
I'm curious to know how they work and the information I found isn't enough so I need a better explanation and also wanna know what can I do with them because I see the programs that use Lua use them to create their global values.
 

GavinW

Newcomer
Creator of RiscLua
Joined
Oct 21, 2020
Messages
50
Reaction score
19
Age
82
Location
UK
Website
www.wra1th.plus.com
Herly, I recommend that you buy Programming in Lua (Fourth Edition) by Roberto Ierusalimschy, if you do not yet have it. You won't regret it. Chapter 22 (The Environment) is what you need. All variables in Lua are either keys in a table or are local to a chunk. So-called global variables are just keys in _ENV. Every chunk comes with a local variable called _ENV. Remember that the whole program is a chunk, the global chunk. All variables in a chunk that are not local to it, or local to a surrounding chunk, are looked up in the table given by that chunk's _ENV. This means that you can use _ENV to simplify your syntax. I don't think that you can do anything in your program with _ENV that you could not do without it, perhaps more clumsily. [This is an invitation to others to rush in and show that I am wrong.]
 

Herly Quijano

Newcomer
Joined
Mar 19, 2021
Messages
70
Reaction score
7
@GavinW I don't know, because I'm not much about reading long texts even if I'm interested in the topic, I do that but is too difficult to me, so I'm not sure in invest 27$ in a book (100 PEN in my country).
 

stetre

Member
Rank: I
Joined
Jan 8, 2020
Messages
95
Reaction score
55
Location
Italy
Website
github.com
You can think of _ENV as a table that implicitly holds your global variables. For example, try running the lua shell and executing the following in it (here the > is the shell prompt):

Lua:
> x = "this is x"
> print(_ENV.x)
> _ENV.x = "this is _ENV.x"
> print(x)

You'll see that the value of _ENV.x is the value you assigned to x, and viceversa. This is because x and _ENV.x are the same thing.

That is, x is not really a 'global' variable but it's actually a field of the table _ENV. You don't have to refer to it as _ENV.x though (but you can if you want to) because Lua automatically understands that you are referring to _ENV.x if there is no local variable with the name x in scope.

The table _ENV is called the environment, which (my guess) is short for the environment where the code is executed in. This gives you a hint on what it can be used for: to create separate environments where to execute different scripts or chunks of code, so that (for example) they can use the same names for 'global' variables without stepping on each other's feet. Or to sandbox them, by providing them an environment with limited functionalities (for example you may not want them to use the io library, so you would provide an _ENV without it).

The table _G is the global environment, which you can think of as the default _ENV. Another experiment you can do in the Lua shell is this:

Lua:
> print(_G)
> print(_ENV)

You'll see that they are the same table.

Yet another experiment that may be helpful in getting to know _ENV (and/or _G) is to print its contents:

Lua:
> for k, v in pairs(_ENV) do print(k, v) end

You'll see that its fields are the exactly the variables that you are likely accustomed to think of as global variables (including the standard libraries, such as 'math', or the core functions such as 'require' or 'print').

When you're comfortable with all the above, the next step is to read the manual entries for load( ) and loadfile( ), which are the functions you use to execute other Lua code from Lua code. They both accept an optional env parameter, which allows you to customize the environment where to execute the loaded code, giving you the opportunity to do things such as those mentioned earlier (sandboxing and separate environments).
 

Herly Quijano

Newcomer
Joined
Mar 19, 2021
Messages
70
Reaction score
7
You can think of _ENV as a table that implicitly holds your global variables. For example, try running the lua shell and executing the following in it (here the > is the shell prompt):

Lua:
> x = "this is x"
> print(_ENV.x)
> _ENV.x = "this is _ENV.x"
> print(x)

You'll see that the value of _ENV.x is the value you assigned to x, and viceversa. This is because x and _ENV.x are the same thing.

That is, x is not really a 'global' variable but it's actually a field of the table _ENV. You don't have to refer to it as _ENV.x though (but you can if you want to) because Lua automatically understands that you are referring to _ENV.x if there is no local variable with the name x in scope.

The table _ENV is called the environment, which (my guess) is short for the environment where the code is executed in. This gives you a hint on what it can be used for: to create separate environments where to execute different scripts or chunks of code, so that (for example) they can use the same names for 'global' variables without stepping on each other's feet. Or to sandbox them, by providing them an environment with limited functionalities (for example you may not want them to use the io library, so you would provide an _ENV without it).

The table _G is the global environment, which you can think of as the default _ENV. Another experiment you can do in the Lua shell is this:

Lua:
> print(_G)
> print(_ENV)

You'll see that they are the same table.

Yet another experiment that may be helpful in getting to know _ENV (and/or _G) is to print its contents:

Lua:
> for k, v in pairs(_ENV) do print(k, v) end

You'll see that its fields are the exactly the variables that you are likely accustomed to think of as global variables (including the standard libraries, such as 'math', or the core functions such as 'require' or 'print').

When you're comfortable with all the above, the next step is to read the manual entries for load( ) and loadfile( ), which are the functions you use to execute other Lua code from Lua code. They both accept an optional env parameter, which allows you to customize the environment where to execute the loaded code, giving you the opportunity to do things such as those mentioned earlier (sandboxing and separate environments).
Thank you for the explanation.
 
Top