Избавление от циклических зависимостей модулей
Итак, у вас есть два модуля, каждый из которых использует другой.
ModuleA.lua:
local ModuleB = require('ModuleB') return { fun1 = function() print('~~~ModuleA fun1') end, fun2 = function() print('~~~ModuleA calls ModuleB.fun1()', ModuleB().fun1()) end, }
ModuleB.lua:
local ModuleA = require('ModuleA') return { fun1 = function() print('~~~ModuleB fun1') end, fun2 = function() print('~~~ModuleB calls ModuleA.fun1()', ModuleA().fun1()) end, }
В главной программе вы наивно пытаетесь их включить:
local ModuleA = require('ModuleA') local ModuleB = require('ModuleB')
и получаете ошибку:
can't load module_test.lua: [string "ModuleB.lua"]:1: loop or previous error loading module 'ModuleA'
Как быть? Шаблон Медиатор приходит на помощь!
ModuleMediator.lua:
return { getModuleA = function() return require('ModuleA') end, getModuleB = function() return require('ModuleB') end, }
Исправляем файлы модулей.
ModuleA.lua:
local ModuleMediator = require('ModuleMediator') return { fun1 = function() print('~~~ModuleA fun1') end, fun2 = function() print('~~~ModuleA calls ModuleB.fun1()', ModuleMediator.getModuleB().fun1()) end, }
ModuleB.lua:
local ModuleMediator = require('ModuleMediator') return { fun1 = function() print('~~~ModuleB fun1') end, fun2 = function() print('~~~ModuleB calls ModuleA.fun1()', ModuleMediator.getModuleA().fun1()) end, }
В главной программе все осталось по старому:
local ModuleA = require('ModuleA') local ModuleB = require('ModuleB') ModuleA.fun1() ModuleA.fun2() ModuleB.fun1() ModuleB.fun2()
Запускаем:
~~~ModuleA fun1
~~~ModuleB fun1
~~~ModuleA calls ModuleB.fun1()
~~~ModuleB fun1
~~~ModuleA fun1
~~~ModuleB calls ModuleA.fun1()
Работает!
Я там маленько ошибся, когда вызывал функцию другого модуля, которая ничего не возвращает, внутри функции print()
, но переписывать не хочется, извините.
Загрузка модулей
Если вы решили часть модулей вынести в отдельную папку, например:
./mylib/
./mylib/Module1.lua
./mylib/Module2.lua
./mylib/Module3.lua
то обращаться к ним из других модулей можно так:
local module1 = require('mylib.Module1')
Только нужно помнить, что в файле с модулем нужно также указывать относительный путь.
Например, в файле ./mylib/Module1.lua нужно написать:
module('mylib.Module1')
Вот здесь http://lua-users.org/wiki/ModulesTutorial написано, как нужно оформлять модули «по-новому».
Мы в своем проекте пока используем функцию module()
. Возможно, вскоре мы от нее откажемся.
leave a comment