This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
H4X0RZ's profile picture

What does setfenv()/getfenv() do?

Started by H4X0RZ, 23 April 2013 - 08:54 AM
H4X0RZ #1
Posted 23 April 2013 - 10:54 AM
Yea, em… I heared something about "enviroment" but I don't know what it does ^_^/>/>
So, if there is a pro, pls help me!
Kingdaro #2
Posted 23 April 2013 - 11:08 AM
An "environment" is simply a table that holds all of the variables for a certain script or function. The global environment for each script is _G. Every global variable/api that you can access is stored in _G.


print(_G.math) --> table:blahblah
print(_G.math.random()) --> some random number

The functions setfenv and getfenv stand for "set function environment" and "get function environment" respectively. It allows you basically overwrite the "_G" of an individual function. So if I had this table:


env = {
  foo = 5;
}

This can be used as an environment, where the variable "foo" is equal to 5. This is a function that attempts to access a global "foo" variable and double it.


function bar()
  foo = foo * 2
end

If we run it on its own, however, we'll get an error, because foo isn't defined for that function.


bar() --> attempt to perform __mul on nil and number (or some error like that)

If we want this function to have access to this foo variable, we use setfenv(). After calling the function, we will see that the variable has changed:


print(env.foo) --> 5
setfenv(bar, env)
bar()
print(env.foo) --> 10
H4X0RZ #3
Posted 23 April 2013 - 11:13 AM
An "environment" is simply a table that holds all of the variables for a certain script or function. The global environment for each script is _G. Every global variable/api that you can access is stored in _G.


print(_G.math) --> table:blahblah
print(_G.math.random()) --> some random number

The functions setfenv and getfenv stand for "set function environment" and "get function environment" respectively. It allows you basically overwrite the "_G" of an individual function. So if I had this table:


env = {
  foo = 5;
}

This can be used as an environment, where the variable "foo" is equal to 5. This is a function that attempts to access a global "foo" variable and double it.


function bar()
  foo = foo * 2
end

If we run it on its own, however, we'll get an error, because foo isn't defined for that function.


bar() --> attempt to perform __mul on nil and number (or some error like that)

If we want this function to have access to this foo variable, we use setfenv(). After calling the function, we will see that the variable has changed:


print(env.foo) --> 5
setfenv(bar, env)
bar()
print(env.foo) --> 10
Thx a lot!
Espen #4
Posted 23 April 2013 - 11:21 AM
Also, as a good function reference I'd suggest this link:
http://www.lua.org/manual/5.2/

Another good site with examples that are easy on the eye:
http://wiki.roblox.com/index.php/Lua_Help
civilwargeeky #5
Posted 23 April 2013 - 02:51 PM
An "environment" is simply a table that holds all of the variables for a certain script or function. The global environment for each script is _G. Every global variable/api that you can access is stored in _G.
But wait! The environment of user-made programs is not _G, it simply has the metamethod "__index" that gets things from _G. Just thought I should point that out.

lua> getfenv() == _G
false
lau> getmetatable(getfenv()).__index
function: 89e2f1
This could be useful to know because if

--First you do
function foo() print("stuff") end
--And later you do
function foo() print("more important stuff") end
Then it may be confusing why your function in _G isn't getting called (personal experience).
PixelToast #6
Posted 23 April 2013 - 02:57 PM
usually you set __index to _G instead of a function
it works the same way
Smiley43210 #7
Posted 23 April 2013 - 08:50 PM
A good example of its use would be in sandboxing a program or setting the environment of a program you're about to run in an OS.