Which states: In this code, the new environment inherits both print and a from the old one. Nevertheless, any assignment goes to the new table. There is no danger of changing a really global variable by mistake, although you still can change them through _G
It also shows that the first print call should return 1
However when running this code, I receive attempt to call a nil value when the first print call is hit.
Any idea why this is happening? I’m probably just being stupid
This happens because in Lua, _G has all of the environment functions, but in Roblox they have sandboxed it to be an empty table that is shared across scripts.
Basically, in your code, you are setting your current environment to an empty table with __index also as an empty table.
Edit:
a = 1;
local newEnv = setmetatable({}, {__index = getfenv()})
setfenv(1, newEnv)
print(a)
a = 10
print(a)
Attempt to call a nil value means you’re trying to call a function which does not exist, in this case it’s print. This is because you’ve created a new environment and not referenced the base meaning all globals will be nil.
local p = print
local newgt = {} -- create new environment
setmetatable(newgt, {__index = _G})
p(print) --> function: 00xxxx
setfenv(1, newgt)
p(print) --> nil
In standard Lua, _G includes methods such as print while in Roblox it does not.
I was referencing the lua docs as linked in the original post for the environment
“the new environment inherits both print and a from the old one”
I think what @TacoBellSaucePackets explained is, _G doesn’t contain the environmental functions in Roblox, therefore the environment I was passing was actually just an empty table - thanks for helping me clear this up.