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 table t with the given name, this table is the module. Otherwise creates a new table t and sets it as the value of the global name and the value of package.loaded[name]. This function also initializes t._NAME with the given name, t._M with the module (t itself), and t._PACKAGE with the package name (the full module name minus last component; see below). Finally, module sets t as the new environment of the current function and the new value of package.loaded[name], so that require returns t.

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))
    end

end

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环境探秘的更多相关文章

  1. lua module package.seeall选项

    module 与 package.seeall http://blog.codingnow.com/2006/02/lua_51_module.html 使用 module("test&qu ...

  2. nginx整合php+lua+oracle环境搭建

    nginx整合php+lua+oracle环境搭建 标签: nginxluaoraclephplinux -- : 1473人阅读 评论() 收藏 举报 分类: 技术() 版权声明:本文为博主原创文章 ...

  3. Lua 学习之基础篇七<Lua Module,Package介绍>

    Lua 之Module介绍 包管理库提供了从 Lua 中加载模块的基础库. 只有一个导出函数直接放在全局环境中: [require]. 所有其它的部分都导出在表 package 中. require ...

  4. nginx + lua +redis环境搭建

    环境搭建,其实主要是lua的环境,这个环境够麻烦的,在网上找了很多前辈的文章,终于完成了 ,安装redis wget http://download.redis.io/releases/redis-3 ...

  5. nginx 与 lua 开发环境搭建

    首先下载最新版的 相关软件 的安装文件. nginx: http://nginx.org/en/download.html LuaJIT: http://luajit.org/download.htm ...

  6. Lua开发环境配置

    Lua(英语发音:/ˈluːə/)程序设计语言是一个简洁.轻量.可扩展的脚本语言,是葡萄牙语中“Luna”(月亮)的意思. Lua is a powerful, fast, lightweight, ...

  7. Nginx详解二十三:Nginx深度学习篇之Nginx+Lua开发环境搭建

    Nginx+Lua开发环境 1.下载LuaJIT解释器wget http://luajit.org/download/LuaJIT-2.0.2.tar.gztar -zxvf LuaJIT-2.0.2 ...

  8. Sublime Text3配置Lua运行环境

    Sublime Text3配置Lua运行环境 前言 要问现在哪个编译器最能扛得住潮流,要数Sublime Text3了,由于它的轻量,插件丰富,美观,造就了一大批粉丝(本菜鸡也是哦) 在以前的工作中使 ...

  9. [转载]使用VS2015搭建Lua开发环境

    参考原文请看: Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境(一) Lua学习笔记2:Windows7下使用VS2015搭建Lua开发环境(二) 本篇主要分以下几个部分: 一 ...

随机推荐

  1. Android 通信 EventBus

    参考: Android 框架炼成 教你如何写组件间通信框架EventBus Android EventBus源码解析 带你深入理解EventBus Android EventBus实战 没听过你就ou ...

  2. 【HDU】1693 Eat the Trees

    http://acm.hdu.edu.cn/showproblem.php?pid=1693 题意:n×m的棋盘求简单回路(可以多条)覆盖整个棋盘的方案,障碍格不许摆放.(n,m<=11) #i ...

  3. 【noiOJ】p7939

    09:膨胀的木棍 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 当长度为L的一根细木棍的温度升高n度,它会膨胀到新的长度L'=(1+n*C)*L,其中C是热 ...

  4. 编码Q&A

    Q:什么是编码? A:由于计算机中所有数据都是以二进制存在,那么为了存储数字,字母,各种符号和文字,计算机必须用一套映射系统来对应.比如我在某台计算机上规定,用00010001这个二进制数表示字母a, ...

  5. 你用java的swing可以做出这么炫的mp3播放器吗?

    这个mp3播放器是基于java的swing编写的,我认为界面还是可以拿出来和大家看一看评一评. 先说说创作的初衷,由于前段时间工作不是很忙,与其闲着,还不如找一些东西来给自己捣腾捣腾,在 之前写的 j ...

  6. 彩色照片转换为黑白照片(Color image converted to black and white picture)

    This blog will be talking about the color image converted to black and white picture. The project st ...

  7. VS开发好用的扩展

    VS开发好用的扩展(转) 转自:http://www.haogongju.net/art/1977373 首先为大家介绍一下开发字体,做程序开发,代码可读性,在侧面也能帮助开发提高效率,所以给大家介绍 ...

  8. 关于IAP的破解

    介绍 大概在今年7月份,有俄罗斯黑客破解了苹果的应用内付费(In-App Purchases),设备在不越狱的情况下就可以免费获得来自苹果官网App Store里应用的收费道具.受影响的产品众多,包括 ...

  9. zk master-slaver机制

    1.基本概念 >>zookeeper handler (zk句柄)有点类似文件句柄,打开一个文件就保持了一个文件句柄!同样的道理: 建立一个到zk server的session就会有一个z ...

  10. 获取Android studio的SHA1值

    D:\Android\BaiduMapsApiASDemo>c: C:\>cd .android 系统找不到指定的路径. C:\>cd Users C:\Users>cd Ad ...