Lua的实现是非常简单而且清晰的,我决定整理一下最近学到的lua知识,我想先从lua的环境开始谈起。
环境是个什么概念呢?在lua中,大部分的结构都可以用table来表达,环境也不例外,环境指的是一张表,这张表里保存这能够使用的全局变量。这样说还是不太清晰,接着看就会明白了。
全局环境是什么呢?Lua有一个大的环境,即 _G 环境。这个是全局环境,保存着全局的变量。可以通过这行代码打印出 _G 环境里的内容:for k, v in pairs(_G) do print(k, v) end,在我的电脑中,显示的结果如下(版本是lua5.1的,所以有部分值在lua5.2中已经看不到了):
下面我们一个一个来弄清楚全局环境里的这些东西从哪来。
lua源码linit.c中,在luaL_openlibs中把下面这个table中对应的内容以及模块的名称放到了 _G 环境中。
在base库里面向 _G 环境添加了23个函数和2个值,这些可以在源文件lbaselib.c里面找到:
内容如下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 环境中。
还剩下8个值:unpack、arg、module、require、getfenv、setfenv、newproxy、gcinfo
unpack在加载table库(ltablib.c)时放入 _G 环境:
arg在lua脚本执行的时候(lua.c)被放入 _G 环境中:
module和require在加载package时(loadlib.c)被放入 _G 环境。
lua5.2中没有把getfenv、setfenv、newproxy、gcinfo放入全局环境中了。lua5.1中还保留这4个值。