Lua学习笔记之模块
模块
require()
使用模块
module()
创建模块
通过require()
来加载一个模块,返回一个全局变量table类型。
local a = require ”mod”
a.foo()
require
函数,搜索模块名时,使用一个 ’ ; ’分隔的路径。
我遇到过一个加载路径的问题,最后得到的结论是:那一串路径中一般第一个:当前路径,是指运行lua脚本的当前位置,不是lua脚本所在的当前路径。通常,会直接到lua脚本所在的地方运行,但也有2个路径有不一样的时候。eg:/home/example/lua_test/test.lua 这是脚本所在路径,运行它时,我可以再/home/example/下面运行,此时test.lua脚本里面的require函数查找的是运行它的路径下模块文件。
编写模块
local modname = ...
local M = { }
_G[ modname ] = M
package.loaded[modname] = M -- 就替代了本模块最后的return
M.i = { r =0 , i =1 }
M.f = function ( r , i )
return { r = r , i = i }
end
当其他文件require这个模块的时候会传递文件名,那么文件名就传递进来作为参数命名这个模块了。
module
函数:编写模块文件第一句。它的作用就是上面描述模块文件的开头几句,并且多加一句
setfenv( 1 , M)将这个table设置为主程序块的环境。
module( ... , package.seeall)
package.seeall选项打开了访问外部(其他模块或者文件中的内容)。
记录一下:使用环境,”函数环境”技术
local modname = ...
local M = { }
_G[modname] = M
package.loaded[modname] = M
setmetatable( M , { __index =_G } ) --继承外部功能使用eg:io,math
setfenv( 1 , M )
以上就是module函数+package.seeall选项的实现过程
或者想要自己实现这个过程,并限制使用外部模块的一部分:
编写如下:
--模块设置
local modname = ...
local M = { }
_G[ modname ] = M
package.loaded[ modname ] = M
--导入段:声明本模块想要使用的外部模块功能作为本模块局部变量
local sqrt = math.sqrt
local io = io
--最后,设置模块的环境
setfenv( 1 , M )
以上
子模块:require加载时,用‘/’代替‘.’
另外,require加载模块时,最后会查找以参数命名的目录下的init.lua文件。
eg:/usr/local/lua/?/init.lua