function require(modname)
if not package.loaded[modname] then
local loadfunc = package.preload[modname]
if loadfunc ~= nil then -- Case 1
package.loaded[modname] = true -- "true" is just to mark module as loaded
local module = loadfunc(modname);
if module ~= nil then
package.loaded[modname] = module -- replace "true" with actual module
end
else -- loadfunc is nil
local fname = string.gsub(modname, "%.", "/") -- replace "." with /; we get a file name
local loaded = false
for each item in package.path do
local luafile = string.gsub(item, "?", fname)
if open luafile success then -- Case 2
loaded = true
package.loaded[modname] = package.loadfile(luafile)
end
end
if not loaded then -- failed to load the module from lua, then try .so files;
for each item in package.cpath do
local sofile = string.gsub(item, "?", fname)
if open sofile success then -- Case 3
loaded = true
package.loaded[modname] = package.loadlib(sofile)
end
end
end
end
end
return package.loaded[modname]
end
这里面有3中情况:
# vim test.lua
print("--------------[package.loaded]--------------")
for n in pairs(package.loaded) do
print(n)
end
print("--------------[package.preload]--------------")
for n in pairs(package.preload) do
print(n)
end
print("--------------[package.path]--------------")
print(package.path)
print("--------------[package.cpath]--------------")
print(package.cpath)
# lua test.lua
--------------[package.loaded]--------------
string
debug
package
_G
io
os
table
math
coroutine
--------------[package.preload]--------------
--------------[package.path]--------------
./?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/lib64/lua/5.1/?.lua;/usr/lib64/lua/5.1/?/init.lua
--------------[package.cpath]--------------
./?.so;/usr/lib64/lua/5.1/?.so;/usr/lib64/lua/5.1/loadall.so
[root@localhost local]#
可见package.preload为空。
# vim test.lua
ngx.say("--------------[package.loaded]--------------")
for n in pairs(package.loaded) do
ngx.say(n)
end
ngx.say("--------------[package.preload]--------------")
for n in pairs(package.preload) do
ngx.say(n)
end
ngx.say("--------------[package.path]--------------")
ngx.say(package.path)
ngx.say("--------------[package.cpath]--------------")
ngx.say(package.cpath)
# vim nginx.conf
<pre name="code" class="plain"> ......
location /test {
default_type 'text/html';
lua_code_cache off;
content_by_lua_file /var/objstore/lua/test.lua;
}
....
# curl -s "http://127.0.0.1:8080/test"
--------------[package.loaded]--------------
coroutine
table
ndk
jit.opt
math
package
os
_G
bit
string
debug
jit
io
ngx
--------------[package.preload]--------------
table.clear
ngx.upstream
ffi
jit.util
table.new
jit.profile
--------------[package.path]--------------
/var/objstore/lualib/?.lua;/usr/local/openresty-1.9.15.1/lualib/?.lua;/usr/local/openresty-1.9.15.1/lualib/?/init.lua;./?.lua;/usr/local/openresty-1.9.15.1/luajit/share/luajit-2.1.0-beta2/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/openresty-1.9.15.1/luajit/share/lua/5.1/?.lua;/usr/local/openresty-1.9.15.1/luajit/share/lua/5.1/?/init.lua;
--------------[package.cpath]--------------
/var/objstore/lualib/?.so;/usr/local/openresty-1.9.15.1/lualib/?.so;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/openresty-1.9.15.1/luajit/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so;
[root@localhost local]#
可见,package.preload里面包含一些函数。
例1: local ok, new_tab = pcall(require, "table.new")
使用Case 1的方式加载,因为package.preload table里有对应得加载函数。
例2:前一篇博客点击打开链接中的 local redis = require "resty.redis"
使用Case 2的方式加载,因为:"resty.redis"的"."替换为"/"得到"resty/redis"。把package.path中的"?"替换为"resty/redis",其中有一项为
/usr/local/openresty-1.9.15.1/lualib/resty/redis.lua
这是一个合法的Lua模块。故加载它。
如前所述,这两个路径是用于搜索Lua模块和C模块的。
若不设置,将使用默认配置。若想在默认配置的基础上,增加更多路径,";;"代表默认配置。例如:
openresty环境:
# vim nginx.conf
lua_package_path "/var/objstore/lualib/?.lua;;";
lua_package_cpath "/var/objstore/lib/?.so;;";
脚本环境:
# vim ~/.bashrc
export LUA_PATH="/var/objstore/lualib/?.lua;;"
export LUA_CPATH="/var/objstore/lib/?.so;;"
# vim test.lua
package.path="/var/objstore/lualib/?.lua;;"
package.cpath="/var/objstore/lib/?.so;;"