Is there a way to have
- Two Lua modules (let's call them
A
andB
) - Each module uses functions from the other, so they must
require
each other - A third module (let's call it
C
) can useA
but notB
e.g.
C.lua
:
local A = require 'A'
-- ...
A.foo()
- There may be another module
D
that requiresB
but notA
and/orE
requiring bothA
andB
- Neither
A
norB
nor their members should be added to the global namespace. - Avoid using the
module
andsetfenv
functions (deprecated in Lua 5.2)
Related: Lua - how do I use one lib from another? (note: this solution does not handle circular dependencies.)
I found quite a simple way to do it:
A.lua
:
local A = {}
local B
function A.foo()
B = B or require 'B'
return B.bar()
end
function A.baz()
return 42
end
return A
B.lua
:
local B = {}
local A
function B.bar()
A = A or require 'A'
return A.baz()
end
return B
A standard way to do this in any language is to introduce a mediator. Modules can then publish and subscribe to the mediator. http://en.wikipedia.org/wiki/Mediator_pattern
An example of this in my languages is mvccontrib bus, IEventAggregator, and MVVM Lite Messenger class. They all do the same thing.
Another method, suggested by Owen Shepherd on the lua-l mailing list:
If we set package.loaded[current-module-name]
at the top of each module, then any other module require
d later can refer to the current (possibly incomplete) module.
A.lua:
local A = {}
package.loaded[...] = A
local B = require 'B'
function A.foo()
return B.bar()
end
function A.baz()
return 42
end
return A
B.lua:
local B = {}
package.loaded[...] = B
local A = require 'A'
function B.bar()
return A.baz()
end
return B
This will not work everywhere. For example if B
's initialization depends on A.baz
then it will fail if A
is loaded first, because B
will see an incomplete version of A
in which baz
is not yet defined.
来源:https://stackoverflow.com/questions/8248698/recommended-way-to-have-2-modules-recursively-refer-to-each-other-in-lua-5-2