Reputation: 3044
I would like to know how to share global variables between Lua scripts.
I tried to do this myself using require
but it doesn't work as I expected.
Here's my simple example code.
In test.lua
num = 2
In A.lua
require(`test`);
num = 5
In B.lua
require(`test`);
print(num);
And if I run A.lua
first, then B.lua
, I get the following result:
2
But I expect to get 5
because I modified the variable value to 2
in A.lua
.
Is it possible to achieve what I want? (I would appreciate an example)
Upvotes: 5
Views: 10643
Reputation: 10939
There is no dedicated function to require Lua modules from the C-API.[1] So I oriented myself on the function dolibrary
in the Lua interpreter to implement require
which simply calls the Lua require
function from C.
N.B.: I don't recommend having modules communicate by sharing global variables, especially when the order of loading the modules matters as is the case here. Better provide methods A.update_num(old)
and B.update_num(old)
which take the old value of num
as an argument and return the updated value.
#include <iostream>
#include <lua.hpp>
int require(lua_State *L, char const * modname) {
int const size = lua_gettop(L);
lua_getglobal(L, "require");
lua_pushstring(L, modname);
if (lua_pcall(L, 1, LUA_MULTRET, 0) != 0) {
std::cerr << "lua:" << lua_tostring(L, 1) << '\n';
lua_pop(L,1);
return 0; // Failed, nothing should be on the stack
}
return lua_gettop(L) - size;
}
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
require(L, "A");
require(L, "B");
lua_close(L);
}
With the scripts from your question in the same directory we get:
$ clang++ -Wall -Wextra -Wpedantic -I /usr/include/lua5.2/ test.cpp -llua5.2
$ ./a.out
5
[1] There is lua_requiref
to require Lua C modules from the C-API.
Upvotes: 1
Reputation: 346
a.lua
a = 5
b.lua
require('a')
a = 2
test.lua
require('b')
print(a)
You should get 2, because the require chain works from top-bottom, if you just run each file a time lua will execute just this little uniq execution, there is no persistency acros diferent executions, so you need to require as needed
Upvotes: 1
Reputation: 2386
What you are currently doing is the following:
lua A.lua
> lua process starts
> loading A.lua
> loading test.lua (because it is required by A.lua)
> set global "num" to value 2
> set global "num" to value 5
> lua process exits (A.lua finished)
lua B.lua
> lua process starts
> loading B.lua
> loading test.lua (because it is required by B.lua)
> set global "num" to value 2
> print global "num" (which was set to 2 by test.lua)
> lua process exits (B.lua finished)
To print the value 5 your scripts should look like this:
-- test.lua
num = 2
-- A.lua
require("test")
num = 5
-- B.lua
require("test")
require("A")
print(num)
which will result in:
lua B.lua
> lua process starts
> loading B.lua
> loading test.lua (because it is required by B.lua)
> set global "num" to value 2
> loading A.lua (because it is required by B.lua)
> skip loading test.lua (has already been loaded)
> set global "num" to value 5
> print global "num"
> lua process exits (B.lua finished)
EDIT: I see you're using the C Api of Lua and not a Lua binary to execute your scripts. Using the programming api you should be able the get your required result by executing A.lua and B.lua using the same lua-state (most commonly stored in the C-Variable "L").
Upvotes: 5