[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: problem with lua_newthread, setfenv and modules
- From: Graham Wakefield <lists@...>
- Date: Mon, 12 May 2008 17:05:21 -0700
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