【发布时间】:2014-03-11 06:28:39
【问题描述】:
我一直在尝试使用 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”。
我已经浏览了其他帖子中提到的Sand Boxes Example,但我仍然得到相同的结果。知道如何在不污染全局环境的情况下在自己的环境中加载脚本吗?
【问题讨论】:
-
似乎
require("Singleton")在全球环境中执行Singleton.lua尽管当前环境。 -
@egor-skriptunoff 你给了我一个想法。它并没有解决整个问题,但取得了一些进展。在 TestTable 中执行以下操作:
local singletonTable = loadfile("C:\\pathto\\Singleton.lua") singletonTable()导致以下输出:niltable: 051D3108InitChangedInitChanged这似乎仍然将 Singleton 加载到全局环境中,但至少保留了实例这次在正确的环境中。
标签: lua env lua-5.1 lua-loadfile