使用 setfenv 定义 Lua 变量范围

标签 lua scope sandbox

我正在尝试使用原始 Lua 文件进行配置,但不希望配置文件污染全局命名空间。

我遇到的问题是 dofile似乎总是在真实的全局环境中执行,所以外部文件只是将它们的所有声明都扔到 _G 中。

这是一个示例主文件,其中的注释表明了我的一厢情愿。

function myFunc()
    print("In the sandbox:")
    print("Should be 1:", a)  -- falls back to _G for lookup
    a = 2  -- instantiating new global for sandbox
    print("Should be 2:", a)  -- from sandbox
    print("Should still be 1:", _G.a)  -- from host environment

    dofile("loading.lua")  -- here's where things go wrong

    print "\nBack in the sandbox:"
    print("Should be 3:", a)  -- changed by loadfile
    print("Should STILL be 1:", _G.a)  -- unchanged
end

a = 1
local newgt = {} -- new environment
setmetatable(newgt, {__index = _G})
setfenv(myFunc, newgt)
myFunc()

print("\nOutside of the sandbox:")
print("Should be 1: ", a)  -- in theory, has never changed

以及它正在加载的文件( loading.lua :
print ("\nLoading file...")

print("Should be 2: ", a) -- coming from the sandbox environment
a = 3
print("Should be 3: ", a) -- made a change to the environment

最后我看到的输出:
In the sandbox:
Should be 1: 1
Should be 2: 2
Should still be 1: 1

Loading file...
Should be 2:  1
Should be 3:  3

Back in the sandbox:
Should be 3: 2
Should STILL be 1: 3

Outside of the sandbox:
Should be 1:  3

最佳答案

您描述的问题也在此页面上讨论 Dofile Namespace Proposal .解决方案似乎是 dofile 的以下替代品:

function myapp.import(name)
  local f,e = loadfile(name)
  if not f then error(e, 2) end
  setfenv(f, getfenv(2))
  return f()
end

另见:Sand Boxes

关于使用 setfenv 定义 Lua 变量范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3098544/

相关文章:

for-loop - for-do 循环结束后获取表值

函数返回 nil,但应该返回 true 或 false

C++:如何将更改应用于动态数组交叉函数?

objective-c - 在沙箱中重新启动后访问同一文件

ios - Corona SDK 应用程序异常退出,信号为 10 : Bus Error: 10. 设备崩溃

lua - 如何使用 Visual Studio 调试 Lua 代码

javascript - 如何将 JavaScript 回调设置为外部(包装)对象的方法?

ruby - 获取先前作用域的局部变量

macos - TOpenDialog/NSOpenPanel 无法在沙盒 Delphi 应用程序中工作

linux - 在我的服务器上运行其他人代码(沙盒)的安全方式?