RectangleEquals
RectangleEquals

Reputation: 1825

Using the 'module' function in Lua 5.2?

I have a VC++ project which uses Lua 5.2 for scripting.
I am trying to implement MySQL compatibility into this project.
I do not own this project, so I would prefer to change as little source code as possible, if any at all.
I have downloaded and unzipped the files from this extension into the same base directory as the executable... and in my Main.lua file, I have added the line require('DBI') as stated to do so on this wiki page.

But when I run the application and execute the script, I get:

LUA Fail:
C:\Path\To\bin\DBI.lua:3: attempt to call global 'module' (a nil value)

After some light reading, I found out that the module function was depreciated in Lua 5.2...
But this extension, as well as other MySQL extensions, require the use of the module function.

So what is a workaround for this issue?

Upvotes: 3

Views: 2574

Answers (2)

Alex
Alex

Reputation: 1017

I used this as a quick and dirty way to get most of my scripting setup working with 5.2. I didn't use module myself but have the likes of luasocket, copas etc in my stack. I doubt this helps in your specific case but may be of some use more generally.

Essentially I replicated the C version of module in lua using the debug library to set the function environment. Not pretty but hey.

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

Upvotes: 1

Paul Kulchenko
Paul Kulchenko

Reputation: 26744

You may need to compile your Lua instance with LUA_COMPAT_MODULE; according to the source code: "LUA_COMPAT_MODULE controls compatibility with previous module functions 'module' (Lua) and 'luaL_register' (C)".

This won't be enough though as the module itself is written with Lua 5.1 API in mind. You can either try to find its Lua 5.2 version or use something like Peter Cawley's TwoFace that "allows a Lua 5.2 program to load most 5.1 C libraries without the need for any recompilation".

Upvotes: 2

Related Questions