This is exactly the reason why Lua modules shouldn't set global variables, but instead export all its functions/variables in a table that gets returned via require
.
However, if your two modules are Lua modules, you can set a custom environment for each so that the global variables that the modules define end up in separate tables:
#!/usr/bin/lua
-- fallback implementation of package.searchpath for Lua 5.1
local searchpath = package.searchpath
-- not necessary if you have Lua 5.2+:
if not searchpath then
local delim = package.config:match( "^(.-)\n" ):gsub( "%%", "%%%%" )
function searchpath( name, path )
local pname = name:gsub( "%.", delim ):gsub( "%%", "%%%%" )
local msg = {}
for subpath in path:gmatch( "[^;]+" ) do
local fpath = subpath:gsub( "%?", pname )
local f = io.open( fpath, "r" )
if f then
f:close()
return fpath
end
msg[ #msg+1 ] = "\n\tnofile '"..fpath.."'"
end
return nil, table.concat( msg )
end
end
-- table for storing the environments for each module
local environments = {}
-- clone of the standard Lua searcher which sets a custom environment
-- for the loaded chunk and stores it in the environments table.
local function my_lua_searcher( modname )
local fpath, msg = searchpath( modname, package.path )
if not fpath then
return msg
end
local env = setmetatable( {}, { __index = _G } )
env._G = env
environments[ modname ] = env
local f = assert( loadfile( fpath, nil, env ) )
if setfenv then -- for Lua 5.1
setfenv( f, env )
end
return f, fpath
end
-- replace the Lua searcher (at index 2)
local searchers = package.searchers or package.loaders
-- if someone added to package.searchers, we have no way of knowing
-- which function is the Lua searcher we want to replace:
assert( #searchers == 4, "package.searchers has been modified" )
searchers[ 2 ] = my_lua_searcher
-- test it:
require( "A" )
require( "B" )
environments[ "A" ].test()
environments[ "B" ].test()