Рекомендуемый способ рекурсивно ссылаться на 2+ модуля в Lua 5.2

Есть ли способ иметь

  • Два модуля Lua (назовем их A а также B)
  • Каждый модуль использует функции другого, поэтому они должны require друг с другом
  • Третий модуль (назовем его C) можешь использовать A но нет B например

C.lua:

local A = require 'A'

-- ...

A.foo()
  • Там может быть другой модуль D что требует B но нет A и / или E требуя как A а также B
  • ни A ни B ни их члены не должны быть добавлены в глобальное пространство имен.
  • Избегайте использования module а также setfenv функции (устарело в Lua 5.2)

Связанный: Lua - как мне использовать одну библиотеку из другой? (примечание: это решение не обрабатывает циклические зависимости.)

3 ответа

Решение

Я нашел довольно простой способ сделать это:

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

Другой метод, предложенный Оуэном Шепардом в списке рассылки lua-l:

Если мы установим package.loaded[current-module-name] вверху каждого модуля, затем любой другой модуль requireПозже я могу обратиться к текущему (возможно, неполному) модулю.

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

Это не будет работать везде. Например, если Bинициализация зависит от A.baz тогда он потерпит неудачу, если A загружается первым, потому что B увидим неполную версию A в котором baz еще не определено.

Стандартный способ сделать это на любом языке - это ввести посредника. Затем модули могут публиковать и подписываться на посредника. http://en.wikipedia.org/wiki/Mediator_pattern

Примером этого в моих языках является шина mvccontrib, IEventAggregator и класс MVVM Lite Messenger. Все они делают одно и то же.

Другие вопросы по тегам