Lua Module对全局变量访问
来源:互联网 发布:linux禅道安装教程 编辑:程序博客网 时间:2024/04/30 12:13
2008年12月9日
今天下午调试程序的时候,遇到了一件非常奇怪的事。弄清楚了之后,才发现原来是Lua中Module中自有环境的问题。
大体情况是这样的,我在主程序中设定的全局变量,在模块文件中可以访问到,并修改了这个全局变量的值,但是在模块调用返回后,再次使用这个全局变量的值,发现它没有被赋值,没有被改变。究其原因,发现是因为Lua的模块里面,采用了自己的全局环境(这个全局环境会将主程序中的全局环境做为备选查找表,即使用__index联系),这与主程序中的全局环境是不一样的(两个不同的表)。模块中如果有一个变量被第一次赋值的话,Lua会认为是在模块的环境中新建一个全局变量,即使这个全局变量与主程序中的全局变量重名,它也不会去引用主程序中的全局变量,然后赋值。
下面举几一个sample来解释这种情况:
主程序文件: test.lua
require "a"
print("================================")
print(GGG[1])
print(GGG[2])
print(SKU[1])
print(SKU[2])
print("================================")
f = require "b"
f.run()
print(GGG[1])
print(GGG[2])
print(SKU[1])
print(SKU[2])
print("================================")
另一个文件: a.lua
GGG = {}
GGG[1] = 10
SKU = {}
模块文件: b.lua
module(..., package.seeall)
function run()
print("--------------------------------")
GGG[2] = 20
print(GGG[1])
print(GGG[2])
SKU = GGG
print(SKU[1])
print(SKU[2])
print("--------------------------------")
return 0
end
运行 lua test.lua 后,结果如下:
================================
10
nil
nil
nil
================================
--------------------------------
10
20
10
20
--------------------------------
10
20
nil
nil
================================
而如果将模块文件 b.lua 改成如下形式:
module(..., package.seeall)
function run()
print("--------------------------------")
GGG[2] = 20
print(GGG[1])
print(GGG[2])
_G.SKU = GGG
print(SKU[1])
print(SKU[2])
print("--------------------------------")
return 0
end
那么结果如下:
================================
10
nil
nil
nil
================================
--------------------------------
10
20
10
20
--------------------------------
10
20
10
20
================================
可以看到,程序修改之前没有对主程序全局变量进行赋值,而修改之后,给主程序全局变量赋了值。
通过本例,我们还可知道,require 既可用来加载模块文件(包括动态链接库模块),也可用来加载普通的代码块文件。模块文件加载进来后,使用一个引用来调用模块中的方法和变量。而普通的代码块文件在被require调入后,就相当于(如果有Local变量,则不完全是)成了主程序代码的一部分,全局变量可以贯穿使用。(非本地)函数也可以直接调用。
Lua的如下语句:
GGG[2] = 20
实际上进行了两个操作,首先是对GGG的引用,如果在当前模块中找不到它的定义,就会通过__index元方法查找到_G中去,如果在_G中找到了,那么就引用_G中的这个GGG变量,并且给它添加一个元素值20。而如果在_G中也没有找到定义,那程序会认为是第一次碰到GGG这个变量,第一次碰到这个变量就要去引用它,并且是引用它其中的一个元素,便会报错。所以,类似这样的数据元素赋值的操作实际上是:引用加索引和赋值三个操作的结合。
而简单的赋值语句就不一样了:
SKU = GGG
这句,会引用GGG,GGG在当前模块找不到的话,会到_G中去找。它也会引用SKU,但它发现,这是这个模块中的第一次出现的变量,并且被赋值(写),于是会当成是一个新的变量来创建。因此,这里的SKU,并非_G中的那个SKU,而仅仅是模块内部的一个变量。究根揭底,还是因为模块的环境与主环境之间只有__index(读回溯),而没有__newindex(写回溯)的缘故。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xenyinzen/archive/2008/12/10/3485633.aspx
- Lua Module对全局变量访问
- Lua Module对全局变量访问
- Lua Module对全局变量访问
- lua防止访问不存在的全局变量
- Lua 全局变量
- lua全局变量
- Lua 全局变量
- Lua Module
- lua module
- Lua Module
- 10.c++给lua传递变量和访问Lua的全局变量
- 多线程学习之一:线程对共享全局变量的访问
- lua 全局变量 2
- LUA中的全局变量环境
- 【lua全局变量_G】
- Lua初识之全局变量
- 04,Lua 全局变量
- Lua module机制分析
- 需求分析-如何进行软件需求分析
- Hadoop的基准测试工具使用(部分转载)
- Set的循环遍历
- (转)ADO.NET中的多数据表操作浅析之读取方案
- 开源游戏引擎KlayGE简介
- Lua Module对全局变量访问
- struts2中result的type中redirectAction和redirect的区别
- TRANSACT SQL 温习
- c++成员变量初始化问题
- OGRE资源相关分析
- 关于windows消息
- SQL SERVER 表提示说明
- Ogre 材质
- VC入门笔记(四)