我一直在尝试使用 setfenv() 以便将一个块加载到全局环境之外的环境中,但我遇到了一些麻烦。以下是我正在运行的代码:
-- main.lua
function SandboxScript(scriptTable, scriptName)
setmetatable(scriptTable, { __index = _G })
local sandbox = loadfile(scriptName)
setfenv(sandbox, scriptTable)
sandbox()
return scriptTable
end
local function main()
print(Singleton)
local test = {}
local single1 = SandboxScript(test, "C:\\pathto\\TestTable.lua")
print(Singleton)
test.Update()
local test2 = {}
local single2 = SandboxScript(test2, "C:\\pathto\\TestTable.lua")
test2.Update()
end
main()
-- TestTable.lua
require("Singleton")
local test = {}
function Update()
test = Singleton:new()
print(test.var)
test.var = "Changed"
print(test.var)
end
-- Singleton.lua
Singleton = {}
Instance = {}
function Singleton:new()
if(next(Instance)) then
return Instance
end
Instance.var = "Init"
return Instance
end
我期望这个的输出是:
nil --(First check in global table before running sandbox code)
nil --(Second check in global table after running sandbox code)
Init --(Initial value of the Singleton's var)
Changed --(Singleton's var after we change it)
Init --(Initial value of the Singleton's var in a different sandbox)
Changed --(Singleton's var after we change it in the different sandbox)
相反,我得到:
nil
table: 05143108
Init
Changed
Changed
Changed
表明“sandbox()”正在将表加载到全局空间中,即使我在执行“sandbox()”之前使用“setfenv(sandbox, scriptTable)”将沙盒的环境设置为“scriptTable”。
我已经浏览了其他帖子中提到的沙盒示例,但我仍然得到相同的结果。知道我可以做些什么来在它自己的环境中加载脚本而不污染全局环境吗?