Reputation: 123
The problem is, a "require" keyword clears all global variables defined in the same file.
I am working on a project in c++. I use lua 5.3. The lua scripting style is:
1 all lua codes contains 1 common library file, and several small files each acting as a function.
2 when program start, the lua common library is compiled and executed, leave its global variables in the lua state. Then the small files are compiled not executed.
3 when program come to some point, relevant small lua file will be called(just as I say, every small file is a function). The global functions and variables defined in the common library will be used in the small lua file. That's why I compile and execute the common library when program start.
4 I'm very sure I only use 1 lua_State.
It worked fine, until I decide to split common library to multiple files, And use "require" in the main file. When program start, the main file will be compiled and executed.
Not a single code changed, just add come "require". Strange thing happened: All global variables and global functions are missing. When global function is called in small lua file, a "called a nil value" error raises.
I then make a experiment, I delete all "require" lines in the main library file, and it turns out that the global functions defined in the main library worked very well. I then require a empty file "simple.lua", the global functions defined in the main library was missing, cannot be called from the small lua file.
How to explain this? How can a "require" keyword clears all global variables defined in the same file?
in lua library:
require("simple")
function foo()
return 1+1
end
in lua small file
return foo()
result: attempt to call a nil value (global 'foo')
after delete "require", lua library:
function foo()
return 1+1
end
result: no error happens, 2 is returned
the c++ side code:
lua common library compile and excute:
int code = luaL_loadbuffer(L, s, strlen(s), "commonlib");
if(code != 0) {
std::string error = lua_tostring(L, -1);
lua_pop(L, 1);
return error;
}
code = lua_pcall(L, 0, 0, 0);
if(code > 0)
{
std::string ret = lua_tostring(L, -1);
lua_pop(L, 1);
return ret;
}
else
return ""; //empty string means no error
lua small function file compile:
int code = luaL_loadbuffer(L, s, strlen(s), "RULE1");
if(code != 0) {
std::string error = lua_tostring(L, -1);
lua_pop(L, 1);
return error;
}
else
{
return ""; //return empty means no error
}
The L in both code is the same lua state (or it won't work when "require" is removed). After compile, the small file function at the stack top is saved in global register with a reference variable "ref". When call lua small file, the ref is pushed in the stack, a lua_pcall is used, nothing special.
Upvotes: 2
Views: 940
Reputation: 123
Resolved the problem by myself. Because of a duplicated copy/paste, the lua vm is created the second time afterwards. It's rather confusing because if there is no "require", everything is alright. It is a total coincidence.
All I learnt from this is: always double check the copy/paste code.
Upvotes: 0