lua-users home
lua-l archive

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


> In general, 'require' a module in will affect all coroutine. Thus if I
> change 'moduleA.b' value in one coroutine, another coroutine will find
> 'moduleA.b' has been changed.
> So I want to know the possiblity to use 'require' to load module in
> different coroutines have independent environment, in this case, changing
> 'moduleA.b' value in one coroutine do not affect another coroutine (like
> libc 'errno').
> I try to use 'setfenv', but it only for global variable, not for 'require'
> and 'module'.

Modules and environments are orthogonal issues.

The modules are cached in the packages.loaded table the first time
they are required. This allows to save time and memory (no need to
execute the module code several time).

If you remove the module's entry in that table, the code will be
evaluated again the next time you require it, and a new table will be
returned.

    function make_thread()
        package.loaded.my_module = nil
        local my_module = require"my_module"
        local thread = function()
            my_module.foo = "bar"
        end
        -- alternative, but no advantage in practice, upvalue access is faster
        --setfenv ( thread,
        --    setmetatable({my_module = require"my_module"},
        --        {__index = _G}
        --    )
        --)
        return coroutine.wrap(thread)
    end

If you only update fields in the module itself, not in its subtables,
you could use wrappers, set their __index metafield to the module, and
save some memory.

    function wrap(mod)
        return setmetatable( {}, {__index=module})
    end

Then replace `require` with `wrap` in the first snippet.

I hope it helps.
-- Pierre-Yves