[转载]lua5.2 require实现
项目客户端脚本全面升级lua5.2 这是自06年后最大的一次主干更新, 带来的机制, 函数变化也是非常不错的
1. 去掉了全局性质的setfenv/getfenv系列函数, 语言层面提供_ENV语法糖, 这东西跟:操作符一样, 只存在于编译期.
官方建议自己实现module/require/package机制, 毕竟原生这套机制实现太弱智了..
2. 提供了无符号访问函数
3. 更多的lua api变化. 如果想兼容lua5.1的写法, 可以参考luabridge内LuaHelpers.h的实现
以下是本人使用lua5.2实现的一套package机制, 供大家参考
package = {} -- 读取标记 package.loaded = {} -- 搜索路径数组 package.path = {} package.access = { ["string"] = string, ["print"] = print, ["table"] = table, ["assert"] = assert, ["error"] = error, ["pairs"] = pairs, ["ipairs"] = ipairs, ["tonumber"] = tonumber, ["tostring"] = tostring, ["type"] = type, ["math"] = math, } local function getreadablepath( name, pathlist ) for _, path in ipairs(pathlist) do local fullpath = path .. "/" .. name .. ".lua" local f = io.open( fullpath ) if f then f:close() return fullpath end end return nil end function package.import( name ) -- 已经读取的直接返回 local existedenv = package.loaded[name] if existedenv then return existedenv end local access = package.access -- 设置访问控制权限 local meta = { __index = function( tab, key ) -- 优先取包的空间 local v = rawget( tab, key ) if v then return v end -- 找不到时,从可访问的权限表中查找 return access[key] end } -- 初始化一个包的全局环境, 并设置访问方法 local env = setmetatable( {} , meta ) -- local readablepath = getreadablepath( name, package.path ) if not readablepath then error(string.format("package '%s' not found \n%s", name, table.concat( package.path, "\n" ) ) ) end local func = loadfile( readablepath, "bt", env ) if type(func) ~= "function" then return nil end -- 设置标记 package.loaded[name] = env -- 执行全局空间 func( ) return env end package.path = {"E:/Download/t"} local m = package.import "m" m.foo() 以下是m模块(m.lua)的内容 function foo( ) print("转载注明: 战魂小筑 http://www.cppblog.com/sunicdavy", io ) end
测试结果中, io打印出nil, 显示权限已经被控制住
本package设计比原生package更灵活, 更强大
浙公网安备 33010602011771号