lua module package.seeall选项
module 与 package.seeall
http://blog.codingnow.com/2006/02/lua_51_module.html
使用
module("test")
后,下面不再看的见前面的全局环境。如果在这个模块里想调用 print 输出调试信息怎么办呢?一个简单的方法是
local print=print
module("test")这样 print 是一个 local 变量,下面也是可见的。或者可以用
local _G=_G
module("test")那么 _G.print 也是可以用的。
当然还有一种巧妙的方式,lua 5.1 提供了一个 package.seeall 可以作为 module 的option 传入
module("test",package.seeall)
这样就 OK 了。至于它们是如何工作的,还是自己读源码会理解的清楚一些。
源码不太好读, 我们下面找文档和做实验来理解。
为啥使用了 package.seeall, 则此module就可以引用全局环境了呢?
文档:
http://www.lua.org/manual/5.1/manual.html
module (name [, ···])This function can receive optional options after the module name, where each option is a function to be applied over the module.
package.seeall (module)Sets a metatable for
modulewith its__indexfield referring to the global environment, so that this module inherits values from the global environment. To be used as an option to functionmodule.
使用package.seeall后, 会将当前module的环境表, 设置个 metatable( {__index=_G})
含义就是, 当你在module声明之后, 如果使用print函数, 则在当前module环境表中存在, 则会想_G表中搜索。
package.seeall
static int ll_seeall (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
if (!lua_getmetatable(L, 1)) {
lua_createtable(L, 0, 1); /* create new metatable */
lua_pushvalue(L, -1);
lua_setmetatable(L, 1);
}
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setfield(L, -2, "__index"); /* mt.__index = _G */
return 0;
}
测试代码
module_test.lua
module(..., package.seeall)
local print = print
local getfenv = getfenv
local tostring = tostring
local getmetatable = getmetatable--module("module_test")
local function printTable(tbl)
for k,v in pairs(tbl) do
print("kay="..tostring(k) .. " value="..tostring(v))
endend
varone = 1
local strkey = "vartwo"
-- 本模块环境
local env = getfenv(1)env[strkey] = 2
print("vartwo="..vartwo)
print("getfenv(1) ="..tostring( ( getfenv(1) ) ) )
print("getfenv(1) metatable="..tostring( getmetatable( getfenv(1) ) ) )
print("--------------- before getmetatable( getfenv(1) ) -------------")
printTable( getmetatable( getfenv(1) ) )
print("--------------- after getmetatable( getfenv(1) ) -------------")-- 调用此模块的环境
local env_caller = getfenv(2)env["env_caller"] = env_caller
print("getfenv(2) ="..tostring(getfenv(2)))
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
getfenv(1) =table: 006F9438
getfenv(1) metatable=table: 006F92D0
--------------- before getmetatable( getfenv(1) ) -------------
kay=__index value=table: 006F2650
--------------- after getmetatable( getfenv(1) ) -------------
getfenv(2) =table: 006F2650
testmodule.vartwo=2
----------- testmodule ------------------
kay=_NAME value=module_test
kay=_PACKAGE value=
kay=varone value=1
kay=_M value=table: 006F9438
kay=vartwo value=2
kay=env_caller value=table: 006F2650
----------- testmodule.env_caller ------------------
kay=string value=table: 006F9730
kay=xpcall value=function: 006F6788
kay=module_test value=table: 006F9438
kay=package value=table: 006F7110
kay=tostring value=function: 006F6968
kay=print value=function: 006F6CC8
kay=os value=table: 006F9848
kay=unpack value=function: 006F6A08
kay=require value=function: 006F7C98
kay=getfenv value=function: 006F6E08
kay=setmetatable value=function: 006F66A8
kay=next value=function: 006F6C88
kay=assert value=function: 006F6D48
kay=tonumber value=function: 006F6888
kay=io value=table: 006F96E0
kay=rawequal value=function: 006F6DC8
kay=collectgarbage value=function: 006F6D28
kay=arg value=table: 006F92A8
kay=getmetatable value=function: 006F6AE8
kay=module value=function: 006F7B98
kay=rawset value=function: 006F6AA8
kay=var_caller value=55
kay=math value=table: 006F96B8
kay=debug value=table: 006F91E0
kay=pcall value=function: 006F6CE8
kay=table value=table: 006F7160
kay=newproxy value=function: 006F0568
kay=type value=function: 006F6A48
kay=coroutine value=table: 006F7340
kay=_G value=table: 006F2650
kay=select value=function: 006F6B48
kay=gcinfo value=function: 006F6D88
kay=pairs value=function: 006F0538
kay=rawget value=function: 006F6A88
kay=loadstring value=function: 006F6B08
kay=ipairs value=function: 006F2BD0
kay=_VERSION value=Lua 5.1
kay=dofile value=function: 006F6DE8
kay=setfenv value=function: 006F6A28
kay=load value=function: 006F6B88
kay=error value=function: 006F6D68
kay=loadfile value=function: 006F6DA8
>Exit code: 0
lua module package.seeall选项的更多相关文章
- Lua 学习之基础篇七<Lua Module,Package介绍>
Lua 之Module介绍 包管理库提供了从 Lua 中加载模块的基础库. 只有一个导出函数直接放在全局环境中: [require]. 所有其它的部分都导出在表 package 中. require ...
- lua module环境探秘
module 作用 module (name [, ···]) Creates a module. If there is a table in package.loaded[name], this ...
- lua --- Module
首先需要明白,一般情况下,我们的定义的lua模块的文件与模块名(其实就是table的名字)是一致的,当然,不一致代码也是可以编译的(亲测),之所以这样,本人认为是为了实际项目中管理的方便.以下是定义模 ...
- python学习笔记之module && package
个人总结: import module,module就是文件名,导入那个python文件 import package,package就是一个文件夹,导入的文件夹下有一个__init__.py的文件, ...
- python模块module package
python模块module package module package 常用模块 模块与包的区别 模块分为内置模块.第三方模块,自定义模块 程序会先从内置到第三方再到当前工作目录下去找你导入的 ...
- Python语法31[module/package+import]
一 module 通常模块为一个文件,直接使用import来导入就好了.可以作为module的文件类型有".py".".pyo".".pyc" ...
- nginx install lua module
#install luajit #http://luajit.org/download.html .tar.gz cd LuaJIT- make install PREFIX=/home/allen. ...
- Module, Package in Python
1.To put it simple, Module是写好的一系列函数或变量,文件以.py为后缀,可以在其他Module中整体或部分引用. PS: 在Module中[结尾或开头]加入if __name ...
- NodeJS require a global module/package in linux
https://stackoverflow.com/questions/15636367/nodejs-require-a-global-module-package 1 export NODE_P ...
随机推荐
- ACM: HDU 1869 六度分离-Dijkstra算法
HDU 1869六度分离 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descri ...
- Selenium_webdriver获取iframe子页面元素
有时候我们在定位一个页面元素的时候发现一直定位不了,反复检查自己写的定位器没有任何问题,代码也没有任何问题.这时你就要看一下这个页面元素是否在一个iframe中,这可能就是找不到的原因之一.如果你在一 ...
- Html5_禁止Html5在手机上屏幕页面缩放
最近测试html5页面,发现默认都允许用户缩放页面,或者在屏幕双击放大或缩小.即相当于这样设置 <meta name="viewport" content="wid ...
- Sping Environment为Null的原因和解决方法
参考:https://github.com/spring-projects/spring-boot/issues/4711 这个issue提出不到20天给我搜出来了,还是相信google的强大 问题: ...
- NHibernate one-to-one
NHibernate里面one-to-one有两种方式:主键关联和唯一外健关联 主键关联: 两个表拥有相同的主键字段,值相同的关联在一起.典型的应用是一个对象的属性太多,将常用的属性跟不常用的附加属性 ...
- javascrit2.0完全参考手册(第二版) 第2章第3节 变量
变量存储数据.每个变量都有一个名字,叫做标识符.在js中声明变量使用var关键字,var为新的数据分配存储空间,或者指示一直标识符正在使用.声明变量非常简单: var x; 这个语句告诉解释器一个新的 ...
- jquery中prop()方法和attr()方法的区别浅析
官方例举的例子感觉和attr()差不多,也不知道有什么区别,既然有了prop()这个新方法,不可能没用吧,那什么时候该用attr(),什么时候该用prop()呢 jquery1.6中新加了一个方法pr ...
- js通过sessionStorage实现的返回上一页
通常,我们都会使用比较熟悉的javascript:history.go(-1)来实现返回上一页,此种方法有一个问题就是返回上一页后不能刷新当前页面,给我们的开发带来了一定的不便,显然有时这种方法就不是 ...
- thinkphp添加空数据的解决办法
thinkphp真是个麻烦的东西,各种小问题,其中字段映射的表单名不能与数据库的字段名称相同,否则会添加空数据! 还有自动完成的名称要与字段映射后的名称相同,否则自动完成不会起作用! 还有自动验证的字 ...
- 诅咒JavaScript之:Jquery ajax提交内容异常
jquery ajax 通过url提交内容,在服务器端获取却出现很奇怪的值,代码如下: ajaxurl = "aspx/logTable.ashx?action=load&Every ...