lua_tinker自从lua5.0出来以后就鲜有更新 ,好在5.1没有对接口作大的修改让lua_tinker平稳的过渡,但到了lua5.2 发布以后 再执行tinker 能得到的也就只有报错的提示了。
关于5.2的修改 网上总结了不少,有不少宏都不用了而tinker恰好用到了其中的几个,比如LUA_GLOBALSINDEX lua_open ,如果简单的用新的宏替换掉旧的
#define LUA_GLOBALSINDEX LUA_RIDX_GLOBALS
#define lua_open luaL_newstate
到能让tinker顺利编译通过,但到了运行simple 的时候 会遇到如下错 attempt to call global 'xxx' (a nil value)
其实对tinker影响最大的 是因为没有global的函数了,所以使用时都要赋给一个表, 原来可有可无的_G 现在被环境_ENV 所取代(对_ENV的理解网上很多自行搜索,这里就不详细说明了),虽然仍有_G但也不过是5.2为了兼容在base_open加了 这么几句
/* set global _G */
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G");
/* open lib into global table */
luaL_register(L, "_G", base_funcs);
5.1用lua_pushstring(L, name); lua_gettable(L, LUA_GLOBALSINDEX); 这么去取全局变量 ,而5.2只能取到 全局下的module表,从取到的module中再取一次才能取到真正想要的东西,而全局的module在_ENV下
为了避免取2次的麻烦,5.2也提供了新的api来完成这种事,就是lua_getglobal和lua_setglobal
所以升级tinker只用做如下几步
- 修改所有lua_pushstring(L, name); lua_gettable(L, LUA_GLOBALSINDEX);为lua_getglobal(L, name)
- 修改所有lua_pushstring(L, name); lua_settable(L, LUA_GLOBALSINDEX);为lua_setglobal(L, name) << 要注意原本压栈的顺序问题
- 还有针对原有的luaopen_string(L); 这种没有默认module名的得用 luaL_requiref(L, "string", luaopen_string, 1); 来给名为 string的module名