_ENV 和 load

简介: _ENV 和 load

函数 load 通常把被加载代码段的上值 _ENV 初始化为全局变量。不过,函数 load 还有一个可选的第四个参数来让我们为 _ENV 指定一个不同的初始值(函数 loadfile 也有一个类似的参数)。


例如,加入我们有一个典型的配置文件,该配置文件定义了程序要使用的几个常量和函数,如下:

-- 文件'config.lua'
width = 200
height = 300
...


可以使用如下的代码加载该文件:

env = {}
loadfile("config.lua", "t", env)()


配置文件中的所有代码会运行在空的环境 env 中,类似于某种沙盒。特别地,所有的定义都会进入这个环境中。即使出错,配置文件也无法影响任何别的东西,甚至是恶意的代码也不能对其他东西造成任何破坏。除了通过消耗 CPU 时间和内存来制造拒绝服务(Denial of ServiceDOS)攻击,恶意代码也做不了什么其他的事。


有时,我们可能像重复运行一段代码数次,每一次使用一个不同的环境。在这种情况下,函数 load 可选的参数就没有用了。此时,我们有另外两种选择。


第一种选择是使用调试库中的函数 debug.setupvalue 。顾名思义,函数 setupvalue 允许改变任何指定函数的上值,例如:

f = load("b = 10; return a")
env = {a = 20}
debug.setupvalue(f 1, env)
print(f())                        --> 20
print(env.b)                      --> 10


setupvalue 的第一个参数是指定的函数,第二个参数是上值的索引,第三个参数是新的上值。对于这种用法,第二个参数永远是 1 :当函数表示的是一段代码时, Lua 语言可以保证它只有一个上值且上值就是 _ENV


这种方式的一个小缺点在于依赖调试库。调试库打破了有关程序的一些常见假设。例如, debug.setupvalue 打破了 Lua 语言的可见性规则,而可见性规则可以保证我们不能从词法定界的范围外访问局部变量。


另一种在几个不同环境中运行代码的方式是每次加载代码段时稍微对其进行一下修改。假设我们在要加载的代码段前加入一行:

_ENV = ...;


注意

由于 Lua 语言把所有的代码段都当做可变长参数函数进行编译,因此,多出的这一行代码会把传给代码段的第一个参数赋值给 _ENV ,从而把参数设为环境。

目录
相关文章
|
6月前
|
JavaScript Unix Linux
⨯ cannot execute cause=fork/exec...pnpm\bin\pnpm.cjs: %1 is not a valid Win32 application.
⨯ cannot execute cause=fork/exec...pnpm\bin\pnpm.cjs: %1 is not a valid Win32 application.
571 0
|
6月前
|
Linux iOS开发 MacOS
pnpm全局安装报错:Run “pnpm setup“ to create it automatically, or set the global-bin-dir setting, or the PN
pnpm全局安装报错:Run “pnpm setup“ to create it automatically, or set the global-bin-dir setting, or the PN
1865 0
|
3月前
|
C++ Windows
vs2019 This application failed to start because it could not find or load the QT platform plugin
这篇文章介绍了在VS2019中解决QT程序运行时出现的“无法找到或加载QT平台插件”错误的步骤,通过将必要的DLL文件和插件目录复制到项目解决方案中解决了问题。
|
3月前
ESLint—— Failed to load config "standard" to extend from
ESLint—— Failed to load config "standard" to extend from
77 0
|
安全 Python
YAML+PyYAML笔记 8 | PyYAML源码之full_load(),full_load_all(),safe_load(),unsafe_load(),unsafe_load_all()
YAML+PyYAML笔记 8 | PyYAML源码之full_load(),full_load_all(),safe_load(),unsafe_load(),unsafe_load_all()
130 1
|
6月前
|
JavaScript 前端开发
ESLint—— Failed to load config “standard“ to extend from
ESLint—— Failed to load config “standard“ to extend from
182 0
|
分布式计算 Java Hadoop
Error: JAVA_HOME is incorrectly set. Please update C:\hadoop-2.5.1\conf\hadoop-env.cmd ‘
Error: JAVA_HOME is incorrectly set. Please update C:\hadoop-2.5.1\conf\hadoop-env.cmd ‘
Could not initialize English chunker/Could not load file from classpath: ‘/en-token.bin‘
Could not initialize English chunker/Could not load file from classpath: ‘/en-token.bin‘
101 0
|
JavaScript 测试技术
env文件里小心$
env文件里小心$
113 0