Chapter 14_3 非全局的环境
关于“环境”的一大问题在于它是全局的,任何对它的修改都会影响程序的所有部分。
例如:若安装一个元表用于控制全局变量的访问,那么整个程序都必须遵循这个规范。
当使用某个库时,没有先声明就使用了全局变量,那么这个程序就无法运行。
在Lua中,全局变量并不需要一定是全局的。甚至可以说Lua没有全局变量。
听上去感觉很奇怪,因为我们一直都在使用全局变量。毫无疑问地,Lua一直在给程序员制造全局变量的错觉。
下面看看是怎么样制造的:
比如在下面的例子中,var1和var2 就是两个自由名字(在任何层都没有被声明的名字):
var1 = var2 +
就像之前我们说的,一个自由名字不会涉及到一个全局变量,至少不会显示地涉及到。
对于_ENV,手册上是这样描述:
Every chunk is compiled in the scope of an external local variable named _ENV , so _ENV itself is never a free name in a chunk.
这里的“external local variable”就是upvalue,也就是_ENV是当前chunk的upvalue。
当Lua编译一个chunk的时候,如果不指定的话,默认使用全局环境初始化它的upvalue _ENV(其实就是引用),它是隐式声明的一个upvalue。
此外,在句法上,Lua解释器会把所有的自由名字 var 翻译为_ENV.var。因此上面的代码可以这样表示:
_ENV.var1 = _ENV.var2 +
Lua将所有的代码块当作匿名函数。Lua编译器在编译代码块的时候是这样的:
local _ENV = <some value>
return function(...)
_ENV.var1 = _ENV.var2 +
end
看上去,这样去操作全局变量挺费解的。但是其实是最简单灵活的方式,但是实现起来有点困难。
总结一下在Lua5.2中操作全局变量的情况:
1>_ENV是当前被编译代码块的upvalue
2>Lua编译器把所有的free name var 当作 _ENV.var
3>load 或loadfile函数 用全局环境去初始化代码块中的第一个upvalue。
_ENV除了在预编译的时候才有特殊意义。跳出编译去看它,其实就是一个简单的普通表。
同样把var 当作 _ENV.var,也只是词法翻译,没有隐含的意思。
这节有点没有懂,以后回来再好好看看。
以上内容来自:《Lua程序设计第二版》和《Programming in Lua third edition》
Chapter 14_3 非全局的环境的更多相关文章
- 理解 Linux 网络栈(2):非虚拟化Linux 环境中的 Segmentation Offloading 技术
本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...
- Dynamics CRM2015 非基础语言环境下产品无法新建的问题
该现象出现在2015版本上,之前从没注意过这个问题不知道以前的版本是否存在. 我的安装包的基础语言是中文,第一张图有添加产品的按钮,切换到英文环境下后就没有了,一开始以为是系统做了隐藏处理,但用工具查 ...
- 客户全局信用控制&非全局信用控制
看个简单的例子 客户信用限额 非全局信用控制 非全局信用控制比较简单,我们看一下全局信用控制 设置: 实现结果:全局&非全局对比
- [Linux]非外网环境下配置lnmp心得
1.安装gcc编译器 基本所有编译安装包都需要gcc编译器,而且编译安装gcc也需要一个编译器,这是一个悖论.所以,这里只能寻求rpm包安装.但是rpm包需要匹配特定的操作系统内核,所以没有一个通用的 ...
- JS的解析与执行过程—全局预处理阶段之全局词法环境对象
问题:有如下代码 var a = 1; function pop() { alert(a); var a = 5; } pop();//执行结果,弹出undefined 这段代码的执行结果为undef ...
- nodejs npm install -g 全局安装和非全局安装的区别
1. npm install xxx -g 时, 模块将被下载安装到[全局目录]中. [全局目录]通过 npm config set prefix "目录路径" 来设置. 比如说, ...
- linux 配置全局jdk环境
1.在usr/local下新建software文件夹(mkdir software),将下载的jdk和tomcat放在此文件夹下 2.解压 tar -xzvf jdk-8u191-linux-x64. ...
- 【winform-窗体快捷键】定义功能窗体快捷键,非全局
这里的快捷键并非系统全局快捷键.仅是普通的当窗体在焦点内发生.有很多种方法,这里列举几种项目中使用到的方法. Alt+*(一般控件快捷键) 这个比较简单,只需为该控件的Text属性声明时加上”(&am ...
- Spring工具类 非spring管理环境中获取bean及环境配置
SpringUtils.java import org.springframework.beans.BeansException; import org.springframework.beans.f ...
随机推荐
- mysql 保存emoji时报,数据库报错:Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x82\xF0\x9F...' for column 'review' at row 1
错误原因:我们可以看到错误提示中的字符0xF0 0x9F 0x98 0x84 ,这对应UTF-8编码格式中的4字节编码(UTF-8编码规范).正常的汉字一般不会超过3个字节,为什么为出现4个字节呢?实 ...
- ECStore图片存储采用阿里云OSS(图片存储)服务
主要功能:ECStore图片存储采用阿里云OSS(图片存储)服务 适用版本:ECStore 授权方式:授权域名使用,付费插件 联系方式: QQ 275553385 mail: jimingson ...
- 前端 TDD 开发
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px ".PingFang SC"; color: #454545 } p.p2 ...
- <密码的实现>输入密码的时候,显示“*”,而不是显示输入内容
一开始还以为用C语言和C++不能实现输入密码的时候显示出“*”而不显示输入的内容呢!没想到偶然的机会试出了用while循环结构可以实现.以下是我整理的C语言和C++的代码,供初学者参考. 这是C语言实 ...
- ACboy needs your help hdu 分组背包问题
Description ACboy has N courses this term, and he plans to spend at most M days on study.Of course,t ...
- sendUserActionEvent() mView== null after clicking on button
this is not a problem related to your code, but related to S4 android version. Same question has bee ...
- Visual Studio下使用jQuery的10个技巧
广泛流行的jQuery是一个开源的,跨浏览器和兼容CSS 3的JavaScript库,你可以用它简化你的JavaScript编码任务和操作(添加,编辑和删除)HTML内容中的DOM元素,本文介绍10个 ...
- Flashbuilder 破解方式 4.6 +4.7(网络资源整理)
Fb4.6 破解方式 安装完成后在安装目录下依次修改下列3个文件: (1).eclipse\plugins\com.adobe.flexbuilder.project_4.6.0.328916\MET ...
- 集线器(HUB),交换机,和路由器的区别
交换机与集线器的区别从大的方面来看可以分为以下三点: 1.从OSI体系结构来看,集线器属于OSI第一层物理层设备,而交换机属于OSI的第二层数据链路层设备.也就意味着集线器只是对数据的传输起到同步.放 ...
- JAVA语法基础(课堂ppt问题总结)
一:运行源代码EnumTest.java,分析运行结果. 代码如下: public class EnumTest { public static void main(String[] args) { ...