问题
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.)
回答1:
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
回答2:
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.
回答3:
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