Recommended way to have 2+ modules recursively refer to each other in Lua 5.2

Is there any way to have

  • Two Lua modules (call them A and B )
  • Each module uses functions from another, so they must require each other
  • The third module (let it be called C ) can use A , but not B for example.

C.lua :

 local A = require 'A' -- ... A.foo() 
  • There may be another module D that requires B , but not A and / or E , requiring both A and B
  • Neither A nor B nor their members should be added to the global namespace.
  • Avoid using module and setfenv functions (deprecated in Lua 5.2)

Related : Lua - how can I use one lib from another? (note: this solution does not handle circular dependencies.)

+5
module lua circular-dependency
source share
3 answers

I found a pretty simple way to do this:

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 
+5
source share

Another method suggested by Owen Shepherd to the lua-l mailing list :

If we set package.loaded[current-module-name] at the beginning of each module, then any other require d module can later 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 the initialization of B depends on A.baz , then it will not work if A is loaded first, because B will see an incomplete version of A in which baz has not yet been defined.

+3
source share

The standard way to do this in any language is to introduce an intermediary. Then the modules can publish and subscribe to the intermediary. http://en.wikipedia.org/wiki/Mediator_pattern

An example of this in my languages ​​is mvccontrib bus, IEventAggregator, and MVVM Lite Messenger. They all do the same.

+2
source share

All Articles