lua require 以及module详解 博客分类: lua开发 luarequeiremodule
程序员文章站
2024-03-15 09:55:59
...
1.require 机制
require 是搜索文件并加载文件,(会避免加载同一个文件)其他同dofile一样,
require是根据模式列表带匹配查找文件的,
如 "?;./1/?.lua" require在搜索的时候会替换其中的?来进行搜索, 同时匹配的结果 比如require("hello")
那么require匹配的结果就是 1. hello 2. ./1/hello.lua
package.path = "?;./1/?.lua" require 根据package.path来进行匹配的
如果虚拟机启动到时候存在LUA_PATH 那么package.path = LUA_PATH 如果没有的话就会设置成 luaconf.h定义的默认值,即"?;?.lua"
ps:package.cpath 跟这个一样,用于加载C类库 路径用的是LUA_CPATH
2. require 处理流程
require(modulename)
1.在package.loaded检查,如存在的话就直接返回它的值
2.在package.preload 检查,如存在则作为loader,调用loader(L)返回
3.根据上述的package.path路径来搜索文件返回(加载的时候会运行加载的文件)
4.根据package.cpath查找c库
5.以第一个"."为分割,将模块名划分为:(main, sub)的形式,根据package.cpath查找main,如果存在,就加载该库并查询相应的接口:luaopen_main_sub,例如:先查找 hello库,并查询luaopen_hello_world接口
6.得到loder后,用modname作为唯一的参数调用该loader函数。当然参数是通过lua的栈传递的,所以loader的原型必须符合lua的规范:int LUA_FUNC(lua_State *L)
ll_require会将这个loader的返回值符给package.loaded[modelname],如果loader不返回值同时 package.loaded[modelname]不存在时, ll_require就会把package.loaded[modelname]设为true。
注意:最后ll_reuqire把package.loaded [modelname]返回给调用者。
此时我再应用时遇到过,如果是require以及module搭配使用 一定要注意module(name)中的 name 必须=modulename 不然在module中没有返回值的情况 只会得到true
3.module的处理流程
module(name,c1,c2)
1.package.loaded[name]是一个table,table将作为一个mod(require加载的文件列表也放在这里)
2.name是一个table,此那么将变成一个mod
3.创建table:package.loaded[name] = {[name]=package.loaded[name], ["_NAME"]=name, ["_M"]=t, ["_PACKAGE"]=*name*(删除了最后的".XXXX"部分)}. 4.依次调用c1,c2:
c1(mod), c2(mod),...
5.将当前模块的环境设置为mod,同时把package.loaded[name] = mod (就是上述的table)
require 是搜索文件并加载文件,(会避免加载同一个文件)其他同dofile一样,
require是根据模式列表带匹配查找文件的,
如 "?;./1/?.lua" require在搜索的时候会替换其中的?来进行搜索, 同时匹配的结果 比如require("hello")
那么require匹配的结果就是 1. hello 2. ./1/hello.lua
package.path = "?;./1/?.lua" require 根据package.path来进行匹配的
如果虚拟机启动到时候存在LUA_PATH 那么package.path = LUA_PATH 如果没有的话就会设置成 luaconf.h定义的默认值,即"?;?.lua"
ps:package.cpath 跟这个一样,用于加载C类库 路径用的是LUA_CPATH
2. require 处理流程
require(modulename)
1.在package.loaded检查,如存在的话就直接返回它的值
2.在package.preload 检查,如存在则作为loader,调用loader(L)返回
3.根据上述的package.path路径来搜索文件返回(加载的时候会运行加载的文件)
4.根据package.cpath查找c库
5.以第一个"."为分割,将模块名划分为:(main, sub)的形式,根据package.cpath查找main,如果存在,就加载该库并查询相应的接口:luaopen_main_sub,例如:先查找 hello库,并查询luaopen_hello_world接口
6.得到loder后,用modname作为唯一的参数调用该loader函数。当然参数是通过lua的栈传递的,所以loader的原型必须符合lua的规范:int LUA_FUNC(lua_State *L)
ll_require会将这个loader的返回值符给package.loaded[modelname],如果loader不返回值同时 package.loaded[modelname]不存在时, ll_require就会把package.loaded[modelname]设为true。
注意:最后ll_reuqire把package.loaded [modelname]返回给调用者。
此时我再应用时遇到过,如果是require以及module搭配使用 一定要注意module(name)中的 name 必须=modulename 不然在module中没有返回值的情况 只会得到true
3.module的处理流程
module(name,c1,c2)
1.package.loaded[name]是一个table,table将作为一个mod(require加载的文件列表也放在这里)
2.name是一个table,此那么将变成一个mod
3.创建table:package.loaded[name] = {[name]=package.loaded[name], ["_NAME"]=name, ["_M"]=t, ["_PACKAGE"]=*name*(删除了最后的".XXXX"部分)}. 4.依次调用c1,c2:
c1(mod), c2(mod),...
5.将当前模块的环境设置为mod,同时把package.loaded[name] = mod (就是上述的table)