Использование функции "модуль" в Lua 5.2?
У меня есть проект VC++, который использует Lua 5.2 для сценариев.
Я пытаюсь реализовать совместимость MySQL в этом проекте.
Я не являюсь владельцем этого проекта, поэтому я бы предпочел изменить как можно меньше исходного кода, если он вообще есть.
Я скачал и разархивировал файлы из этого расширения в тот же базовый каталог, что и исполняемый файл... и в моем Main.lua
файл, я добавил строку require('DBI')
как указано, чтобы сделать это на этой вики-странице.
Но когда я запускаю приложение и выполняю скрипт, я получаю:
LUA Fail:
C:\Path\To\bin\DBI.lua:3: attempt to call global 'module' (a nil value)
После небольшого чтения я обнаружил, что функция модуля в Lua 5.2 устарела...
Но это расширение, как и другие расширения MySQL, требует использования функции модуля.
Так что же такое обходной путь для этой проблемы?
2 ответа
Возможно, вам придется скомпилировать ваш экземпляр Lua с помощью LUA_COMPAT_MODULE; согласно исходному коду: "LUA_COMPAT_MODULE контролирует совместимость с предыдущими функциями модуля" модуль "(Lua) и" luaL_register "(С)".
Этого будет недостаточно, поскольку сам модуль написан с учетом API Lua 5.1. Вы можете либо попытаться найти его версию Lua 5.2, либо использовать что-то наподобие TwoFace Питера Коули, которое "позволяет программе Lua 5.2 загружать большинство библиотек 5.1 C без необходимости какой-либо перекомпиляции".
Я использовал это как быстрый и грязный способ заставить большинство моих скриптов работать с 5.2. Я сам не использовал модуль, но в моем стеке есть такие, как luasocket, copas и т. Д. Я сомневаюсь, что это помогает в вашем конкретном случае, но может быть более полезным.
По сути, я реплицировал C-версию модуля в lua, используя библиотеку отладки для установки функциональной среды. Не красиво, но эй.
if not module then
function module(modname,...)
local function findtable(tbl,fname)
for key in string.gmatch(fname,"([%w_]+)") do
if key and key~="" then
local val = rawget(tbl,key)
if not val then
local field = {}
tbl[key]=field
tbl = field
elseif type(val)~="table" then
return nil
else
tbl = val
end
end
end
return tbl
end
assert(type(modname)=="string")
local value,modul = package.loaded[modname]
if type(value)~="table" then
modul = findtable(_G,modname)
assert(modul,"name conflict for module '"..modname.."'" )
package.loaded[modname] = modul
else
modul = value
end
local name = modul._NAME
if not name then
modul._M = modul
modul._NAME = modname
modul._PACKAGE = string.match(modname,"([%w%._]*)%.[%w_]*$")
end
local func = debug.getinfo(2,"f").func
debug.setupvalue(func,1,modul)
for _,f in ipairs{...} do f(modul) end
end
function package.seeall(modul)
setmetatable(modul,{__index=_G})
end
end