lua module环境探秘
module 作用
module (name [, ···])Creates a module. If there is a table in
package.loaded[name], this table is the module. Otherwise, if there is a global tabletwith the given name, this table is the module. Otherwise creates a new tabletand sets it as the value of the globalnameand the value ofpackage.loaded[name]. This function also initializest._NAMEwith the given name,t._Mwith the module (titself), andt._PACKAGEwith the package name (the full module name minus last component; see below). Finally,modulesetstas the new environment of the current function and the new value ofpackage.loaded[name], so thatrequirereturnst.
http://blog.csdn.net/chenyufei1013/article/details/4438801
当在模块文件中使用module函数的时候,如下所示;
module “mymodule”
。。。
实际上等同于以下的语句:
local modname = “mymodule” – 定义模块名
local M = {} -- 定义用于返回的模块表
_G[modname] = M -- 将模块表加入到全局变量中
package.loaded[modname] = M -- 将模块表加入到package.loaded中,防止多次加载
setfenv(1,M) -- 将模块表设置为函数的环境表,这使得模块中的所有操作是以在模块表中的,这样定义函数就直接定义在模块表中
。。。
return M
module被require后返回的对象
整个module文件, 可以看做是一个函数,详见lua chunk解释:
http://www.lua.org/manual/5.1/manual.html
2.4.1 – Chunks
The unit of execution of Lua is called a chunk. A chunk is simply a sequence of statements, which are executed sequentially. Each statement can be optionally followed by a semicolon:
chunk ::= {stat [`;´]}There are no empty statements and thus '
;;' is not legal.Lua handles a chunk as the body of an anonymous function with a variable number of arguments (see §2.5.9). As such, chunks can define local variables, receive arguments, and return values.
从上可以看出, module改变了匿名函数的行为, 返回的是 module构造的局部表(env), 此表在module文件中定义, 然后在module声明之后的语句执行前, 被设置为整个匿名函数的环境, 待module声明之后的语句全部执行完毕, (非local的一些变量, 则会在运行环境env中记录下来, 这个变量相对local来说是开放的,开放到环境中, local变量则生存在匿名函数中, 函数运行结束, 则local消失, 但是env中记录的非local变量得以保存)。
module中如何设置key为变量值的元素
在module文件中, 由于其运行环境是隐式的, 代码中无法直接同名字面量来引用到这个环境, 那么对于一种特殊情况, 需要在环境中记录一些key-value对, 但是key是来自于变量, 如何实现?
由于整个文件是一个chunk, 即匿名函数, 故可以借助getfenv,来获取运行环境。
local strkey = "vartwo"
-- 本模块环境
local env = getfenv(1)env[strkey] = 2
module中如何引用调用者的环境
既然module文件是一个chunk对应一个一名函数, 则可以通过getfenv(2), 来获取此函数的调用者,
即谁require此文件的函数, 这个函数运行的环境, 即为调用者环境。
-- 调用此模块的环境
local env_caller = getfenv(2)env["env_caller"] = env_caller
实验代码
module_test.lua
module(..., package.seeall)
varone = 1
local strkey = "vartwo"
-- 本模块环境
local env = getfenv(1)env[strkey] = 2
print("vartwo="..vartwo)
-- 调用此模块的环境
local env_caller = getfenv(2)env["env_caller"] = env_caller
main.lua
local testmodule = require("module_test")
var_caller = 55
print("testmodule.vartwo=" .. testmodule.vartwo)
local function printTable(tbl)
for k,v in pairs(tbl) do
print("kay="..tostring(k) .. " value="..tostring(v))
endend
print("----------- testmodule ------------------")
printTable(testmodule)
print("----------- testmodule.env_caller ------------------")
printTable(testmodule.env_caller)
运行输出结果:
>lua -e "io.stdout:setvbuf 'no'" "main.lua"
vartwo=2
testmodule.vartwo=2
----------- testmodule ------------------
kay=_NAME value=module_test
kay=_PACKAGE value=
kay=varone value=1
kay=_M value=table: 005F9410
kay=vartwo value=2
kay=env_caller value=table: 005F2650
----------- testmodule.env_caller ------------------
kay=string value=table: 005F9398
kay=xpcall value=function: 005F6CE8
kay=module_test value=table: 005F9410
kay=package value=table: 005F7160
kay=tostring value=function: 005F6CC8
kay=print value=function: 005F6808
kay=os value=table: 005F95A0
kay=unpack value=function: 005F6AE8
kay=require value=function: 005F8078
kay=getfenv value=function: 005F6788
kay=setmetatable value=function: 005F6C48
kay=next value=function: 005F66E8
kay=assert value=function: 005F68A8
kay=tonumber value=function: 005F6CA8
kay=io value=table: 005F94D8
kay=rawequal value=function: 005F6828
kay=collectgarbage value=function: 005F6668
kay=arg value=table: 005F92D0
kay=getmetatable value=function: 005F6688
kay=module value=function: 005F7FD8
kay=rawset value=function: 005F6A28
kay=var_caller value=55
kay=math value=table: 005F9348
kay=debug value=table: 005F90F0
kay=pcall value=function: 005F6988
kay=table value=table: 005F72C8
kay=newproxy value=function: 005F0568
kay=type value=function: 005F6D08
kay=coroutine value=table: 005F70C0
kay=_G value=table: 005F2650
kay=select value=function: 005F6708
kay=gcinfo value=function: 005F69E8
kay=pairs value=function: 005F0538
kay=rawget value=function: 005F6908
kay=loadstring value=function: 005F67C8
kay=ipairs value=function: 005F2BD0
kay=_VERSION value=Lua 5.1
kay=dofile value=function: 005F67A8
kay=setfenv value=function: 005F6A08
kay=load value=function: 005F6888
kay=error value=function: 005F6768
kay=loadfile value=function: 005F6848
>Exit code: 0
lua module环境探秘的更多相关文章
- lua module package.seeall选项
module 与 package.seeall http://blog.codingnow.com/2006/02/lua_51_module.html 使用 module("test&qu ...
- nginx整合php+lua+oracle环境搭建
nginx整合php+lua+oracle环境搭建 标签: nginxluaoraclephplinux -- : 1473人阅读 评论() 收藏 举报 分类: 技术() 版权声明:本文为博主原创文章 ...
- Lua 学习之基础篇七<Lua Module,Package介绍>
Lua 之Module介绍 包管理库提供了从 Lua 中加载模块的基础库. 只有一个导出函数直接放在全局环境中: [require]. 所有其它的部分都导出在表 package 中. require ...
- nginx + lua +redis环境搭建
环境搭建,其实主要是lua的环境,这个环境够麻烦的,在网上找了很多前辈的文章,终于完成了 ,安装redis wget http://download.redis.io/releases/redis-3 ...
- nginx 与 lua 开发环境搭建
首先下载最新版的 相关软件 的安装文件. nginx: http://nginx.org/en/download.html LuaJIT: http://luajit.org/download.htm ...
- Lua开发环境配置
Lua(英语发音:/ˈluːə/)程序设计语言是一个简洁.轻量.可扩展的脚本语言,是葡萄牙语中“Luna”(月亮)的意思. Lua is a powerful, fast, lightweight, ...
- Nginx详解二十三:Nginx深度学习篇之Nginx+Lua开发环境搭建
Nginx+Lua开发环境 1.下载LuaJIT解释器wget http://luajit.org/download/LuaJIT-2.0.2.tar.gztar -zxvf LuaJIT-2.0.2 ...
- Sublime Text3配置Lua运行环境
Sublime Text3配置Lua运行环境 前言 要问现在哪个编译器最能扛得住潮流,要数Sublime Text3了,由于它的轻量,插件丰富,美观,造就了一大批粉丝(本菜鸡也是哦) 在以前的工作中使 ...
- [转载]使用VS2015搭建Lua开发环境
参考原文请看: Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境(一) Lua学习笔记2:Windows7下使用VS2015搭建Lua开发环境(二) 本篇主要分以下几个部分: 一 ...
随机推荐
- Android 实用开源控件
图片放大缩小: PinchImageView 体验最好的图片手势控件,不同分辨率无缝切换,可与ViewPager结合使用. GestureViews 带有手势控制的ImageView和FrameLay ...
- android 第三方 图表
1.XCL-Charts 直接利用Canvas api画出图形,各有好处. XCL-Chart尽量把图的绘制逻辑封装在类中,而把绘制相关的各 个元素开放出来,目的是在保证开发效率的同时,给程序员足够多 ...
- Excel中COUNTIFS函数统计词频个数出现次数
Excel中COUNTIFS函数统计词频个数出现次数 在Excel中经常需要实现如下需求:在某一列单元格中有不同的词语,有些词语相同,有的不同(如图1所示).需要统计Excel表格中每个词语出现的 ...
- LightOJ 1245 数学题,找规律
1.LightOJ 1245 Harmonic Number (II) 数学题 2.总结:看了题解,很严谨,但又确实恶心的题 题意:求n/1+n/2+....+n/n,n<=2^31. ...
- Android在智能终端领域的关键技术专题讲座(成都站)
Android系统引领了终端智能化的浪潮,在民用.公 共及工业等诸多领域得到了广泛的应用,涉及手持终端.电视.汽车导航.工业控制等,在云计算.设备智能化等方面表现卓越.Android也凭借着自身的优 ...
- linux共享内存实验
顾名思义,消息队列就是一些消息的列表,用户可以在消息队列中添加消息和读取消息等.从这点上看,消息队列具有一定的FIFO特性,但是它可以实现消息的随机查询,比FIFO具有更大的优势.同时,这些消息又是存 ...
- Linux watch 监控系统状态
1.linux下watch命令的基本用法 # watch --helpUsage: watch [-dhntv] [--differences[=cumulative]] [--help] [--in ...
- nginx“虚拟目录”不支持php的解决办法
这几天在配置Nginx,PHP用FastCGI,想装一个phpMyAdmin管理数据库,phpMyAdmin不想放在网站根目录 下,这样不容易和网站应用混在一起,这样phpMyAdmin的目录就放在别 ...
- iOS中的通知
一.了解几个相关的类 1.NSNotification 这个类可以理解为一个消息对象,其中有三个成员变量. 这个成员变量是这个消息对象的唯一标识,用于辨别消息对象. @property (readon ...
- php以post方式向接口发送数据
工作需要,我负责收集服务器数据,然后定时向中心服务器发送.我看到了接口信息,需要设置heads头信息,需要发送数据,且是post方式. 这里就用到了curl //发送post请求 function r ...