项目客户端脚本全面升级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更灵活, 更强大