What I would do is, I'd write(or even override) _G, run your function/program, and then restore it.
function callSandboxed(newGlobals, func)
local oldGlobals = {} --make a new table to store the values to be writen (to make sure we don't lose any values)
for i,_ in pairs(newGlobals) do
table.insert(oldGlobals, _G[i]) --Store the old values
_G[i] = newGlobals[i] --Write the new ones
end
func() --Call your function/program with the new globals
for i,v in pairs(oldGlobals) do
_G[i] = v --Restore everything
end
end
In this case, what you want to do is:
--Paste the callSandboxed function
callSandboxed({abs=math.abs},function()print(abs(-1))end) --Prints 1
If you want to remove ALL the old values from _G (not only the ones you want to replace), then you could use this:
function betterCallSandboxed(newGlobals, func) --There's no point deep copying now, we will replace the whole table
local oldGlobals = _G --Make a new table to store the values to be writen (to make sure we don't lose any values)
_G = newGlobals --Replace it with the new one
func() --Call your function/program with the new globals
_G = oldGlobals
end
Now if inside func, print and math(etc) are nil.