Lua的实现是非常简单而且清晰的,我决定整理一下最近学到的lua知识,我想先从lua的环境开始谈起。

环境是个什么概念呢?在lua中,大部分的结构都可以用table来表达,环境也不例外,环境指的是一张表,这张表里保存这能够使用的全局变量。这样说还是不太清晰,接着看就会明白了。

全局环境是什么呢?Lua有一个大的环境,即 _G 环境。这个是全局环境,保存着全局的变量。可以通过这行代码打印出 _G 环境里的内容:for k, v in pairs(_G) do print(k, v) end,在我的电脑中,显示的结果如下(版本是lua5.1的,所以有部分值在lua5.2中已经看不到了):

Lua5.2中的全局环境_第1张图片

 

下面我们一个一个来弄清楚全局环境里的这些东西从哪来。

lua源码linit.c中,在luaL_openlibs中把下面这个table中对应的内容以及模块的名称放到了 _G 环境中。

Lua5.2中的全局环境_第2张图片

在base库里面向 _G 环境添加了23个函数和2个值,这些可以在源文件lbaselib.c里面找到:

Lua5.2中的全局环境_第3张图片

内容如下25个值:

_G、_VERSION、assert、collectgarbage、dofile、error、getmetatable、ipairs、loadfile、load、loadstring、next、pairs、pcall、print、rawequal、rawlen(lua5.2中增加的,lua5.1中没有)、rawget、rawset、select、setmetatable、tonumber、tostring、type、xpcall

然后是9个模块的名字对应的table,在lualib.h里可以找到定义,分别是:coroutine、table、io、os、string、bit32(lua5.2中增加的,lua5.1中没有)、math、debug、package,他们在linit.c中由luaL_requiref(luaxlib.c)函数放入 _G 环境中。

Lua5.2中的全局环境_第4张图片

还剩下8个值:unpack、arg、module、require、getfenv、setfenv、newproxy、gcinfo

unpack在加载table库(ltablib.c)时放入 _G 环境:

Lua5.2中的全局环境_第5张图片

arg在lua脚本执行的时候(lua.c)被放入 _G 环境中:

Lua5.2中的全局环境_第6张图片

module和require在加载package时(loadlib.c)被放入 _G 环境。

lua5.2中没有把getfenv、setfenv、newproxy、gcinfo放入全局环境中了。lua5.1中还保留这4个值。