This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Backup for getfenv
Started by EveryOS, 02 May 2018 - 05:12 PMPosted 02 May 2018 - 07:12 PM
Posted 02 May 2018 - 07:32 PM
Whilst it's only disabled when the disable_lua51_features config option is enabled, it's generally better to use _ENV and the environment arguments to load/loadfile instead of using getfenv and setfenv. As it ensures compatibility into the future. You can always do _ENV or getfenv() if you want to handle pre-1.74 versions, though I don't personally think it's worth the issue.
For more information, see this section of the manual.
For more information, see this section of the manual.
Posted 02 May 2018 - 08:04 PM
But what if I had an already-defined function that I won't to know the _ENV of? Is there like a metatable or something to help?
Posted 02 May 2018 - 08:24 PM
Nope.* You'll sadly have to find other ways to do whatever you are planning/needing to do.But what if I had an already-defined function that I won't to know the _ENV of? Is there like a metatable or something to help?
*It's technically possible to do it with the debug API, but CC doesn't have that either.
Posted 03 May 2018 - 09:07 AM
I think setfenv and getfenv are removed for security reasons, but you can keep track of all environments, if you need to.
Example (keeping track of all env of a custom application starter):
That is the way, how you could keep track of environments. If your program is structured like this, then write a simple getEnv(nID) [nID is not the level, but the running program] method and replace it with your getfenv method.
Example (keeping track of all env of a custom application starter):
local tRunningPrograms = {}
local function createCustomEnv(path)
local tEnv = { __runningProgram = path }
local tMetatable = { __index = _G }
setmetatable(tEnv, tMetatable)
return tEnv, tMetatable
end
function run(sPath, ...)
local tEnv, tMetatable = createCustomEnv(sPath)
tRunningPrograms[#tRunningPrograms + 1] = {
path = sPath,
env = tEnv,
metatable = tMetatable
}
os.run(tEnv, sPath, ...)
end
function prohibit(nID, sAPI)
-- Note: This prohibition can be easily broken, if the program says: <sAPI> = nil,
-- Then it have to know what proxy you are using -> it must be designed for your proxy
-- There are some workarrounds, but this is just a demonstration of accessing environments.
tRunningPrograms[nID].env[sAPI] = false
end
That is the way, how you could keep track of environments. If your program is structured like this, then write a simple getEnv(nID) [nID is not the level, but the running program] method and replace it with your getfenv method.
Edited on 03 May 2018 - 08:50 AM
Posted 03 May 2018 - 09:24 AM
One very minor thing worth mentioning is that setmetatable returns the first table (except in a couple of edge cases, but that's a LuaJ quirk). This means tEnv and tMetatable are the same value.-snip-
Posted 03 May 2018 - 10:52 AM
One very minor thing worth mentioning is that setmetatable returns the first table (except in a couple of edge cases, but that's a LuaJ quirk). This means tEnv and tMetatable are the same value.
Oh, just forgot it, thank you for mentioning. Edited. Please explain in which edge cases LuaJ quirks!
Posted 03 May 2018 - 11:11 AM
Setting the __mode key on a metatable will return a copy of the table instead of modifying the original one. This is a bug and is fixed in CC:Tweaked (and I believe in later versions of LuaJ).Please explain in which edge cases LuaJ quirks!