关于“环境”的一大问题在于它是全局的,任何对它的修改都会影响程序的所有部分。

例如:若安装一个元表用于控制全局变量的访问,那么整个程序都必须遵循这个规范。

当使用某个库时,没有先声明就使用了全局变量,那么这个程序就无法运行。

  在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 非全局的环境的更多相关文章

  1. 理解 Linux 网络栈(2):非虚拟化Linux 环境中的 Segmentation Offloading 技术

    本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...

  2. Dynamics CRM2015 非基础语言环境下产品无法新建的问题

    该现象出现在2015版本上,之前从没注意过这个问题不知道以前的版本是否存在. 我的安装包的基础语言是中文,第一张图有添加产品的按钮,切换到英文环境下后就没有了,一开始以为是系统做了隐藏处理,但用工具查 ...

  3. 客户全局信用控制&非全局信用控制

    看个简单的例子 客户信用限额 非全局信用控制 非全局信用控制比较简单,我们看一下全局信用控制 设置: 实现结果:全局&非全局对比

  4. [Linux]非外网环境下配置lnmp心得

    1.安装gcc编译器 基本所有编译安装包都需要gcc编译器,而且编译安装gcc也需要一个编译器,这是一个悖论.所以,这里只能寻求rpm包安装.但是rpm包需要匹配特定的操作系统内核,所以没有一个通用的 ...

  5. JS的解析与执行过程—全局预处理阶段之全局词法环境对象

    问题:有如下代码 var a = 1; function pop() { alert(a); var a = 5; } pop();//执行结果,弹出undefined 这段代码的执行结果为undef ...

  6. nodejs npm install -g 全局安装和非全局安装的区别

    1. npm install xxx -g 时, 模块将被下载安装到[全局目录]中. [全局目录]通过 npm config set prefix "目录路径" 来设置. 比如说, ...

  7. linux 配置全局jdk环境

    1.在usr/local下新建software文件夹(mkdir software),将下载的jdk和tomcat放在此文件夹下 2.解压 tar -xzvf jdk-8u191-linux-x64. ...

  8. 【winform-窗体快捷键】定义功能窗体快捷键,非全局

    这里的快捷键并非系统全局快捷键.仅是普通的当窗体在焦点内发生.有很多种方法,这里列举几种项目中使用到的方法. Alt+*(一般控件快捷键) 这个比较简单,只需为该控件的Text属性声明时加上”(&am ...

  9. Spring工具类 非spring管理环境中获取bean及环境配置

    SpringUtils.java import org.springframework.beans.BeansException; import org.springframework.beans.f ...

随机推荐

  1. openstack私有云布署实践【11.2 计算nova - compute节点配置(办公网环境)】

    这里我只使用compute1节点配置为示例,其它节点的配置基本是一样的,只是声明的管理IP不同而已   计算节点 # yum install openstack-nova-compute sysfsu ...

  2. 关于FlagsAttribute

    最近在看C#本质论,有介绍FlagsAttribute的特性,看了下源码,发现只是一个简单的特性class和一个构造函数. 调试了一下.NET的源码,发现在console.writeline(***) ...

  3. hdu 2087 剪花布条 kmp模板题

    也是kuangbin专题的 专题名字太长 不复制了…… 刚好数据结构也学了kmp 找一道题敲敲模板…… 暴力的字符串匹配是O(n*m)的时间复杂度 而kmp通过一个O(m)的预处理将字符串匹配的时间复 ...

  4. 【翻译】创建Cordova项目

    下载或者更新Node.js到最新版本 在电脑终端输入命令来安装Cordova CLI sudo npm install -g cordova 如果使用Windows电脑,需要在使用cmd命令行输入 n ...

  5. svn添加新文件自动忽略

    背景:做项目,用的客户端TortoiseSVN1.8,发现新建的文件,不是问号(?),而是自动忽略的减号,提交的时候也确实没有,说明不是符号混乱,确实是被忽略了,网上找了解决方案记录如下: 查看svn ...

  6. JAVA17.1.12流程学习,潜心学习,少说多做,脚踏实地,一心一意。

  7. MyEclipse中用Maven创建Web项目

    方法/步骤     new --> other   1.Wizards: mvaen 2.Maven Project 3.Next   Use Default Workspace Locatio ...

  8. 重读The C programming Lanuage 笔记四:c预处理

    C预处理器执行宏替换.条件编译以及包含指定的文件.以#开头的命令行就是与处理器的对象.这些命令行的语法独立于语言的其他部分,它们可以出现在任何地方,其作用可延续到所在编译单元的末尾(与作用域无关).行 ...

  9. javascript keycode

    keycode    8 = BackSpace BackSpacekeycode    9 = Tab Tabkeycode   12 = Clearkeycode   13 = Enterkeyc ...

  10. 关于用PS改变图像颜色

    由于写的一个页面主色调变了,里面的一些图标颜色也要相应改变,自己难得重新去psd里面截图,就想着用ps,看能否直接能变换一下图标颜色.其实方法也很简单的. 1:用ps打开需要改变图标颜色的文件,然后选 ...