创建模块的基本方法的缺点在于,忘记使用local,很容易就污染全局空间。

“函数环境”是一种有趣的技术,它能够解决上面的问题。就是让模块的主程序块独占一个环境。

这样不仅它的所有函数可以共享这个table,而且它的所有全局变量也都记录在这个table中。还可以将所有的公有函数声明为全局变量。

这样它们就自动地记录在一个独立的table中了。模块所要做的就是将这个table赋予模块名和package.loaded:

local M = {}
_ENV = M
function add (c1,c2)
return new(c1,r + c2.r, c1.i + c2.i)
end

当我们声明add函数后,它自动就到M.add中去了。在该模块中调用其它函数时,也不再需要前缀,new就会去找M.new。

这样在调用一个导出的函数与一个私有函数就没有任何区别可言。就算忘记写local也不会污染全局命名空间,只会将一个私有函数变成了公有而已。

但是问题来了:我们改变了_ENV环境变量,导致我们无法访问之前的全局变量。

这里有几种方法可以解决(褒贬不一):

1》继承

local M = {}
setmetatable(M,{__index = _G})
_ENV = M

现在module可以直接访问全局标识符,每次访问只需要付出很小的开销。这种方法导致了一个后果,从概念上说,此时的模块中包含了所有的全局变量。

例如,通过该模块调用正弦函数:

complex.math.sin(x)

感觉像有点越界,不受控制了。

2》用局部变量保存旧环境

local M = {}
local _G = _G
_ENV = M -- or _ENV = nil

此方法必须在所有全局变量的名称前加上"_G",由于没有涉及到元方法,这种访问会比前面的方法快些。

3》只加载需要的模块或函数(以local变量的方式)

--模块设置
local M = {} -- Import section: 导入段
-- declare everything this module needs from outside
-- 声明这个模块需要从外部引入的所有东西
local sqrt = math.sqrt
local io = io
-- no more external access after this point
--之后就不再需要外部的访问了
_ENV = nil -- or _ENV = M

这种方法比较正规,但是这种技术要求做更多的工作,但是它能清晰地说明模块的依赖性。

同时,比之前俩个方法运行的速度更快,应为它使用了local 变量。

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

Chapter 15_3 使用环境的更多相关文章

  1. PHP微信H5支付开发

    近来公司项目要求用到微信H5开发,因为微信开发文档处处都是坑,我也走了不少弯路,现在就把H5支付的过程记录一下,已备后用!! 首先 先去商户平台申请开通 H5支付!!!! 我们从微信官方下载H5支付d ...

  2. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion

    本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...

  3. Chapter 14_3 非全局的环境

    关于“环境”的一大问题在于它是全局的,任何对它的修改都会影响程序的所有部分. 例如:若安装一个元表用于控制全局变量的访问,那么整个程序都必须遵循这个规范. 当使用某个库时,没有先声明就使用了全局变量, ...

  4. chapter 14_1 环境

    Lua将其所有的全局变量保存在一个常规的table中,称为“global environment”. Lua将环境table自身保存在一个全局变量_G中,_G._G等于 _G . 比如下面的代码打印出 ...

  5. 客户端使用java,服务端使用c++的corba编程环境搭建

    我们先用c++实现服务端和客户端,然后再用java编写客户端. 1. 首先安装omniORB,omniORB提供 omniidl命令,以及一些头文件和库. omniORB一般是需要你自己进行编译. 2 ...

  6. Neutron VxLAN + Linux Bridge 环境中的网络 MTU

    1. 基础知识 1.1 MTU   一个网络接口的 MTU 是它一次所能传输的最大数据块的大小.任何超过MTU的数据块都会在传输前分成小的传输单元.MTU 有两个测量层次:网络层和链路层.比如,网络层 ...

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

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

  8. HBase权威指南环境配置

    出处:http://wuyudong.com/1958.html 系统采用ubuntu-14.04,64bit 1.安装git sudo apt-get install git 出现下面错误:Err ...

  9. WITCH CHAPTER 0 [cry] 绝密开发中的史克威尔艾尼克斯的DX12技术演示全貌

    西川善司的[WITCH CHAPTER 0  cry]讲座 ~绝密开发中的史克威尔艾尼克斯的DX12技术演示全貌   注:日文原文地址: http://pc.watch.impress.co.jp/d ...

随机推荐

  1. ACM沈化校赛

    答对两道题,因为比赛经验原因明明可以对四道,在这两道题又浪费过多时间,成绩不理想,但也是累积了一下经验.

  2. The APR based Apache Tomcat Native library tomcat启动错误

    The APR based Apache Tomcat Native library which allows optimal performance in production environmen ...

  3. 连接pgsql

    package com.jpzhutech.select; import java.sql.Connection; import java.sql.DriverManager; import java ...

  4. cursor属性

    cursor光标类型 auto default none context-menu help pointer progress wait cell crosshair text vertical-te ...

  5. db2 常用配置

    db2set配置: db2set DB2_ENABLE_LDAP=NO db2set DB2_ALTERNATE_GROUP_LOOKUP=GETGROUPLIST db2set DB2_RESTOR ...

  6. Dojo的UI框架bootstrap for dojo和Dojo-Bootstrap简介

    最近在学习Dojo,但样式问题真是头疼呀,虽然清新的淡蓝色很是减缓眼睛的疲劳,但这个扁平化简约风盛行的年代,光是清新的拟物已经满足不了群众的需求了,所以就在这样的需求下,我知道了bootstrap f ...

  7. JavaFX基础学习之URLConnection

    一个标准的JavaFX文件包含三个部分:主类 . 控制类. 界面设计(XML+CSS) 1,main.java package application; import javafx.applicati ...

  8. 汉字转全拼音函数优化方案(SQLServer),值得你看看

    函数要求实现功能 select 函数名 ('你好,我是追索') 返回的结果(ni hao , wo shi zhui suo) 解决方案一: 解决方案一 /* 根据汉字获取全拼 1.生成所有读音临时表 ...

  9. 非root用户搭建hadoop伪分布式

    0.安装软件列表 jdk-7u25-linux-x64.tar.gz hadoop-2.5.0.tar.gz hadoop-native-64-2.5.0.tar   1.准备Linux环境(root ...

  10. Python基础篇-day11 - 协程

    本节主要内容: 1.Gevent协程2.Select\Poll\Epoll异步IO与事件驱动3.RabbitMQ队列 1.Gevent协程 1.1协程的好处 无需线程上下文切换的开销无需原子操作锁定及 ...