Lua Module对全局变量访问

2008年12月9日今天下午调试程序的时候,遇到了一件非常奇怪的事。弄清楚了之后,才发现原来是Lua中Module中自有环境的问题。大体情况是这样的,我在主程序中设定的全局变量,在模块文件中可以访问到,并修改了这个全局变量的值,但是在模块调用返回后,再次使用这个全局变量的值,发现它没有被赋值,没有被改变。究其原因,发现是因为Lua的模块里面,采用了自己的全局环境(这个全局环境会将主程序中的全局环境做为备选查找表,即使用__index联系),这与主程序中的全局环境是不一样的(两个不同的表)。模块中如果有一个变量被第一次赋值的话,Lua会认为是在模块的环境中新建一个全局变量,,即使这个全局变量与主程序中的全局变量重名,它也不会去引用主程序中的全局变量,然后赋值。下面举几一个sample来解释这种情况:主程序文件: test.lua另一个文件: a.lua模块文件: b.lua运行 lua test.lua 后,结果如下:

nil

那么结果如下:可以看到,程序修改之前没有对主程序全局变量进行赋值,而修改之后,给主程序全局变量赋了值。通过本例,我们还可知道,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(写回溯)的缘故。

诚实是人生绝妙的法宝。虽然对人诚实,

Lua Module对全局变量访问

相关文章:

你感兴趣的文章:

标签云: