load在加载代码块时,通常使用全局环境去初始化代码块的_ENV上值。

然而,load选项的第四个参数给出的值就是供_ENV用的。(loadfile函数参数也是一样)

举一个有关初始化的例子,假如我们有一个普通的配置文件,定义了一些常量和函数供程序使用。

--file 'config.lua '
width =
height =
...

然后用下面的代码加载:

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

配置文件中的代码就会在空环境env中运行。

有时,需要多次运行同一块代码,每次运行的环境表都不同。

上面的情况中,load的额外参数就满足不着了。有两个选择可以满足该需求:

第一个,使用debug库的debug.setupvalue 函数。允许改变给定函数的任何上值:

f = loadfile(name)
...
env = { }
gebug. setupvalue(f,,env)

该函数的第一个参数是函数,第二个参数是上值的索引,第三个参数是upvalue的新值。

对于修改环境变量的情况:就是针对第一个参数是load 或loadfile 返回的一个函数,Lua会保证它只有唯一的一个_ENV 上值。这时setupvalue 的第二个参数永远是1。

这种情况的选择有一个不好的缺点是依赖debug库。

第二个选择,就是在加载代码前做点手脚。比如加载前加上下面的一行代码:

_ENV = ...

之前提到过,Lua 编译代码块时,把它当作变参函数。因此,上面的那一行代码会被当作chunk代码块的第一个参数。

因此就用它设置了环境。加载完这段代码块,我们再调用执行代码块后的返回函数。该函数就完成了把目标环境当作第一个参数传递过去。例如:

f = loadwithprefix("local _ENV = ...;",io.lines(filename,"*L"))
...
env = {}
f(env)

Chapter 14_5 _ENV和load的更多相关文章

  1. _ENV和_G

    5.1之前, 全局变量存储在_G这个table中, 这样的操作:a = 1 相当于:_G['a'] = 1 但在5.2之后, 引入了_ENV叫做环境,与_G全局变量表产生了一些混淆,需要从原理上做一个 ...

  2. Chapter 14_4 使用_ENV

    因为_ENV是一个普通的变量,我们可以像其他变量一样去对它进行赋值和访问. _ENV = nil 上面的赋值操作,将会使得在它之后的代码块不能直接访问全局变量.不过,对控制你的代码所使用的变量有用处. ...

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

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

  4. Chapter 3: Connector(连接器)

    一.概述 Tomcat或者称之为Catalina(开发名称),可以简化为两个主要的模块,如下图: 多个Connector关联一个Container.之所以需要多个Connector,是为了处理多种协议 ...

  5. EFFECTIVE OBJECTIVE-C 2.0 TIPS 总结 CHAPTER 1 & CHAPTER 2

    下面只是对读到的所有 Tips 结合我平时开发中遇到的问题进行总结,每一个 Tips 和书中的每一条对应,本文的目的是去掉书中的大部分讨论的内容,让人能够马上使用这些 Tips,建议阅读过原书后食用更 ...

  6. advanced dom scripting dynamic web design techniques Part One DOM SCRIPTING IN DETAIL CHAPTER 1 DO IT RIGHT WITH BEST PRACTICES

    You’re excited; your client is excited. All is well. You’ve just launched the client’s latest websit ...

  7. advanced dom scripting dynamic web design techniques Chapter 2 CREATING YOUR OWN REUSABLE OBJECTS

    JavaScript is all about objects. Objects are the foundation of everything, so if you’re unfamiliar w ...

  8. Chapter 6 — Improving ASP.NET Performance

    https://msdn.microsoft.com/en-us/library/ff647787.aspx Retired Content This content is outdated and ...

  9. Chapter 7. Dependency Management Basics 依赖管理基础

    This chapter introduces some of the basics of dependency management in Gradle. 7.1. What is dependen ...

随机推荐

  1. CUDA开发时用到的各种Linux命令

    cat 读取文件中的全部内容. 例:cat cuda_add.cu

  2. 一个简单的例子说明windows环境变量配置

    关于win下环境变量的问题 配置环境变量其实就像是创建一个快捷键一样,我们把安装程序的路径告诉系统环境变量,这样下次我们在命令行中就可以直接使用一个简单的命令来调用我们安装的程序,因为此时计算机已经知 ...

  3. XTU 1249 Rolling Variance

    $2016$长城信息杯中国大学生程序设计竞赛中南邀请赛$G$题 前缀和. 把公式化开来,会发现只要求一段区间的和以及一段区间的平方和就可以了. #pragma comment(linker, &quo ...

  4. css-ie6下实现最小,最大宽度

    _width: expression((document.documentElement.clientWidth||document.body.clientWidth)<1040?"1 ...

  5. linux/windows平台生成随机数的不同方法

    linux平台,使用rand.Seed() //rand_linux.go package main import ( "math/rand" "time" ) ...

  6. RedHat9.0下载地址

    RedHat下载:http://archive.download.redhat.com/pub/redhat/linux/9/en/iso/i386/

  7. JSON文件处理

    牛X的JSON解析JSON字符串显示字典键值 public void ResolveJson() { //定义的JSON字符串,注意JSON的格式 string str = @” { “”Name”” ...

  8. WinForm 无边框窗体和timer控件

    一.无边框窗体 1.控制按钮如何制作就是放置可以点击的控件,不局限于使用按钮或是什么别的,只要可以点击能触发点击事件就可以了 做的好看一点,就是鼠标移入,移出,按下三个事件会让按钮改变样式 如何获取图 ...

  9. setcookie 设置无效

    转载请署名 achieverain,谢谢 经常见人问PHP程序无法设置cookie.下面把我遇见过的情况都说一遍 1 PHP程序在执行setcookie之前有输出. 解决 :    把setcooki ...

  10. 关于Windows Boot Manager、Bootmgfw.efi、Bootx64.efi、bcdboot.exe 的详解

    1. http://bbs.wuyou.com/forum.php?mod=viewthread&tid=303679&fromuid=396698