Eagle Lau
Eagle Lau

Reputation: 123

Global variables missing after using require in lua

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

Answers (1)

Eagle Lau
Eagle Lau

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

Related Questions