Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用setfenv的Lua变量作用域_Lua_Scope_Sandbox - Fatal编程技术网

使用setfenv的Lua变量作用域

使用setfenv的Lua变量作用域,lua,scope,sandbox,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 ne

我试图使用原始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

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

另请参见:

您打印的是文字1而不是a的值。如果这是一个剪切粘贴作业,那么您的代码是错误的,这就是为什么您会看到令人痛苦的最后一行。哈!谢谢,胖手指至少是结尾的罪魁祸首。感谢您的捕获。感谢您的链接。为了封装从该页面获得的相关知识,请对于这个问题:
dofile
始终在全局命名空间中运行,忽略其调用函数的环境。尝试使用
setfenv
直接影响它会引发错误。相同的限制不适用于从
loadfile
返回的匿名编译函数,因此使用上面的代码你绕过了这个限制。@SJML,没错。我的理解是,
dofile
有点像stock
print
。它的存在是为了给新手和学习者带来极大的方便,特别是在交互式提示下。严肃的代码要么避免使用该函数,要么重新定义它,以便在现实世界中安全地工作。