luaL_openlib replacement for Lua 5.2
Asked Answered
W

1

26

I am adapting a library written for Lua < 5.2 and got to a call I don't know the equivalent of:

luaL_openlib(L, "Polycore", polycoreLib, 0);

Where polycoreLib is a

static const struct luaL_Reg polycoreLib []

How can I replace the call to luaL_openlib?

The lua wiki only states:

Calls such as luaL_openlib(L, name, lreg, x); should be carefully rewritten because a global table with the given name will be searched and possibly created.

Warp answered 27/9, 2013 at 1:13 Comment(0)
S
37

There's two answers to this: one for replicating the behaviour of earlier versions here (where a global table is created), and one for implementing the behaviour that is now conventional (which is to create and return an anonymous table).

For the former:

lua_newtable(L);
luaL_setfuncs(L, polycoreLib, 0);
lua_setglobal(L, "Polycore");

This isn't quite the same as luaL_openlib, because if there is an existing global table Polycore it will overwrite it rather than merging with it. If merging is a concern, use lua_getglobal first, then if it pushed a table re-use that rather than creating a new one:

lua_getglobal(L, "Polycore");
if (lua_isnil(L, -1)) {
  lua_pop(L, 1);
  lua_newtable(L);
}
luaL_setfuncs(L, polycoreLib, 0);
lua_setglobal(L, "Polycore");

The latter is easier because you don't need to care about merging:

lua_newtable(L);
luaL_setfuncs(L, polycoreLib, 0);
return 1;

With this approach, it is the caller's reponsibility to bind the table, as in:

local Polycore = require "Polycore"
Secretion answered 27/9, 2013 at 1:22 Comment(4)
So I have multiple objects that are adding their own function calls to a global library. Trying to figure out how to do that in 5.3 always leads me back to this answer but this answer does not have enough information for me. The first code block overwrites previous entries. The fix for that throws nil reference issues on the lua_getglobal() call, and I dont see how the last one does any sort of look up OR binds to the name "Ploycore". What am I missing?Favela
Additionally the return 1 at the end makes it feel like it is meant to be in a luaopen_Polycore() call... Can I do my meta table creation in there after the luaL_newlib() call safely? (I was getting my gettop() calls to be wrong). (and luaL_newlib() is a wrapper for the lua_newtable() luaL_setfuncs() calls.. kinda)Favela
@Favela luaL_setfuncs uses the table on the top of the stack. So merging with an existing table just involves putting that table on the stack instead of a new table. If that fetched table is already available from a global name then it will remain available from a global name. You, obviously, can't merge tables with the same keys. If you need that (or sub-tables) then you need to handle that manually somehow. (Sub-tables being easy as you just create a new table and insert it into the fetched table.)Nosegay
Yes, you can do anything you need in the luaopen_Polycore call you just need to get your stack right at the end. It might also make more sense to ask a new question referencing this one and add the lua 5.3 bit and your extra goals and show the code you've tried instead of bountying this answered questions (since a new answer on this wouldn't necessarily answer the originally asked question).Nosegay

© 2022 - 2024 — McMap. All rights reserved.