因为_ENV是一个普通的变量,我们可以像其他变量一样去对它进行赋值和访问。

_ENV = nil

上面的赋值操作,将会使得在它之后的代码块不能直接访问全局变量。不过,对控制你的代码所使用的变量有用处。

local print , sin = pirnt , math.sin
_ENV = nil
print() --> 13
print(sin()) --> 0.42016703682664
print(math.cos()) -- error 访问全局变量都会引发错误

我们可以明确地用_ENV来绕过局部变量的声明。

a =                -- global
local a =
print(a) --> 12 (local)
print(_ENV.a) --> 13 (global)

一个主要用途是用它去改变一块代码的环境。一旦你改变了环境,所有的全局访问都会使用这个新的表:

_ENV = {}      --把当前环境清空
a = -- 在_ENV里创建一个域
print(a) --> stdin:4 attempt to call global 'print' (a nil value )

可以看到,在调用print的时候提示为nil。说明清空的_ENV里没有了print这样的全局变量。

因此,要做的应该是通过老的_G 把它移植过来。

a =   --create a global variable
_ENV = {g = _G }   --用旧的_G去改变新环境
a = --在新的_ENV 中创建 a
g.print(a) --> 1
g.print(g.a) --> 15 ,通过g可以在任何地方使用print函数,也可以用_G替代g

在Lua中,_G就是一个普通的名字。只有当Lua在创建一个原始全局表和把它赋为全局变量_G时,它才有了特殊的状态。

Lua其实不关心这个变量的值。但是每当我们要涉及到全局变量时,习惯上都是用它。

另一个要使用你的新环境的方法是用继承。

a  =
local newgt = {} --create new environment
setmetatable(newgt , {__index = _G})
_ENV = newget -- set it
print(a) --> 1

在这个代码中,从老的环境里继承了point 和 a 变量。

任何访问都是去访问新的table。无论怎么去访问,修改都不会对老的环境造成影响,除非通过_G去修改它的值。

作为一个普通的变量,_ENV遵循一般的域规则。

在一个chunk块中定义的函数,在访问其他外部变量时,实际会访问_ENV。

_ENV = {_G = _G}
local function foo()
_G.print(a) --compiled as '_ENV._G.print(_ENV.a)'
end
a = --_ENV.a
foo() --
_ENV = {_G = _G,a = }
foo() --

如果我们定义一个新的_ENV局部变量,当在涉及到自由名字时就会用这个新定义的变量。

a =
do
local _ENV = { print = print, a=}
print(a) --
end
print(a) --2 (back to the orignal _ENV)

因此,定义一个带有私有环境的函数不是什么难事。

function factory(_ENV)
return function()
return a --"global" a
end
end
f1= factory{a = }
f2 = factory{a = }
print(f1()) --
print(f2()) --

factory函数创建了一个返回全局变量a的闭合函数。

当创建闭合函数的时候,这可见的_ENV变量就是闭合函数factory的_ENV参数。

因此,闭合函数就会用这个外部变量(作为上值)访问自由名字。

使用这个域规则,可以用一些其他方法操作环境。

比如,可以用几个函数共享一个环境,或者用一个函数去修改被其他函数共享的环境。

Chapter 14_4 使用_ENV的更多相关文章

  1. Chapter 14_5 _ENV和load

    load在加载代码块时,通常使用全局环境去初始化代码块的_ENV上值. 然而,load选项的第四个参数给出的值就是供_ENV用的.(loadfile函数参数也是一样) 举一个有关初始化的例子,假如我们 ...

  2. Modern C++ CHAPTER 2(读书笔记)

    CHAPTER 2 Recipe 2-1. Initializing Variables Recipe 2-2. Initializing Objects with Initializer Lists ...

  3. Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- ApiWrapper

    前面两片文章讲解了通过AIDL和Messenger两种方式实现Android IPC.而本文所讲的并不是第三种IPC方式,而是对前面两种方式进行封装,这样我们就不用直接把Aidl文件,java文件拷贝 ...

  4. Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- Messenger

    Messenger类实际是对Aidl方式的一层封装.本文只是对如何在Service中使用Messenger类实现与客户端的通信进行讲解,对Messenger的底层不做说明.阅读Android Prog ...

  5. [转]第四章 使用OpenCV探测来至运动的结构——Chapter 4:Exploring Structure from Motion Using OpenCV

    仅供参考,还未运行程序,理解部分有误,请参考英文原版. 绿色部分非文章内容,是个人理解. 转载请注明:http://blog.csdn.net/raby_gyl/article/details/174 ...

  6. 《深入理解计算机系统》 Chapter 7 读书笔记

    <深入理解计算机系统>Chapter 7 读书笔记 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(货被拷贝)到存储器并执行. 链接的时机 编译时,也就是 ...

  7. 《Linux内核设计与实现》Chapter 3 读书笔记

    <Linux内核设计与实现>Chapter 3 读书笔记 进程管理是所有操作系统的心脏所在. 一.进程 1.进程就是处于执行期的程序以及它所包含的资源的总称. 2.线程是在进程中活动的对象 ...

  8. PRML Chapter 2. Probability Distributions

    PRML Chapter 2. Probability Distributions P68 conjugate priors In Bayesian probability theory, if th ...

  9. PRML Chapter 1. Introduction

    PRML Chapter 1. Introduction 为了防止忘记,要把每章的重要内容都记下来,从第一章开始 2012@3@28 今天又回去稍微翻了一下第一章内容,发现第一次看的时候没有看透,每次 ...

随机推荐

  1. [安全学习环境]Win7 下DVWA安装指南

    一.环境依赖: .Net Framework 3.5 PHP+MySQL 集成测试环境:XAMPP V3.2.1 二.环境准备 1.下载XAMPP(http://www.wampserver.com/ ...

  2. LanSoEditor_common ---android平台的视频编辑SDK

    当前版本是LanSoEditor-v1.4 主要使用在音视频的: 裁剪,剪切,分离,合并,转换,拼接,水印,叠加,混合,转码等场合; 我们是针对android平台对ffmpeg做了硬件加速优化,经过多 ...

  3. Servlet源码初探

    年底,公司的事情告一段落,就来捣鼓一下这个Servlet源码,为下一步的spingmvc源码初探做准备 1.Servlet接口 public interface Servlet { void init ...

  4. CodeForces 670F Restore a Number

    模拟. 首先暴力找到答案的位数,然后就是分类讨论输出答案. #pragma comment(linker, "/STACK:1024000000,1024000000") #inc ...

  5. 用Python做SVD文档聚类---奇异值分解----文档相似性----LSI(潜在语义分析)

    转载请注明出处:电子科技大学EClab——落叶花开http://www.cnblogs.com/nlp-yekai/p/3848528.html SVD,即奇异值分解,在自然语言处理中,用来做潜在语义 ...

  6. js的严格模式

    严格模式: 严格模式这下的主要区别如下: 严格模式下的好处:

  7. google谷歌翻译插件-网页一键翻译

    上个月转载的一篇博文,是推荐的四款非常实用的翻译插件,这几天看这个chrome插件网首页有新增了一个google谷歌翻译插件.我能说实话,这款插件比之前推荐的4款翻译插件更好用吗?也不能完全说是更好用 ...

  8. python socket服务器进行远程升级

    # coding:utf-8from socket import *import binascii, linecache, time ServerUrl = "127.0.0.1:900&q ...

  9. jarring type lambda

    object IntStateMonad extendsMonad[({type IntState[A] = State[Int, A]})#IntState] {...}This syntax ca ...

  10. vs2010帮助文档下载以及帮助查看器(H3Viewer)的使用

    在工作中遇到想查看vs2010的帮助文档.推荐使用H3Viewer.一个第三方的免费软件,独立于VS2010运行的帮助查看器.这方面的资料并不多.把本次自己使用的心得分享给大家. H3Viewer官方 ...