lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

I have an application in which lua scripts may be loaded by the user. Each script is given a 'child' lua_State created by lua_newthread(). Keeping each table's variables separate is beneficial to the application, so the child state is given a local environment, with a metatable __index to the master globals, like this:

		lua_State *Ls = lua_newthread(L);
		
// Create a local environment with a link to global environment via __index metamethod
		// this means that script variables are not shared between scripts
		lua_pushthread(Ls);
			lua_newtable( Ls );
				lua_pushvalue( Ls, -1 );
				lua_setmetatable( Ls, -2 ); //Set itself as metatable
				lua_pushvalue( Ls, LUA_GLOBALSINDEX );
				lua_setfield( Ls, -2, "__index" );
			lua_setfenv( Ls, -2 );
		lua_pop(Ls, 1);

A user script can load a module using require (e.g. require "lfs"), which works as normal. However, if a second script is loaded, the global 'lfs' is not accessible to the second script.

script 1:

require "lfs"
print(lfs) -- table (0x....)

script 2:

require "lfs"
print(lfs) -- nil
print(package.loaded.lfs) -- table (0x...)

I can't quite figure out why the second script doesn't get global access to the module. I wonder if the require() call is pushing the module as a global into script 1's environment, rather than the master state. Is this the case? [in fact, does lua_setfenv() on a lua_State do the same as lua_replace(Ls, LUA_GLOBALSINDEX)?]

Is there a known workaround?

Thanks,

Graham