У нас есть довольно большое USSD-приложение, которое использует модуль Erlang gen_fsm для управления пунктами меню.
Текущая версия имеет один файл menus_fsm.erl
, содержащий более 5000 строк кода, связанного с gen_fsm. Наша следующая версия дает нам возможность разделить menus_fsm.erl
на отдельные файлы, чтобы сделать его более удобным в обслуживании в будущем.
В старой версии для отображения меню справки мы делаем следующее (help_menu/1
вызывается из непоказанного кода, отображающего главное меню):
-module(menus_fsm).
% Snipped some irrelvant code
help_menu(StateData) ->
% Display the first menu
send_menu(StateData, "Please Select:\n1. Option 1\n2. Option 2"),
{next_state, waitHelpMenuChoice, StateData, ?MENU_TOUT};
waitHelpMenuChoice(Params, StateData) ->
io:format("Got Help menu response: ~p", [Params]),
doTerminate(ok,"Help Menu", StateData).
Я пропустил большую часть кода, показывающего точку входа в FSM и так далее.
В новой версии мы хотим переместить help_menu/1
и waitHelpMenuChoice/2
в новый модуль help_menu
, который вызывается из menus_fsm
, вот так:
-module( help_menu ).
% Snipped some irrelevant code
help_menu(StateData) ->
menus_fsm:send_menu(StateData, "Please Select:\n1. Option 1\n2. Option 2"),
{next_state, waitHelpMenuChoice, StateData, ?MENU_TOUT};
waitHelpMenuChoice(Params, StateData) ->
io:format("Got Help menu response: ~p", [Params]),
menus_fsm:doTerminate(ok,"Help Menu", StateData).
Проблема в строке {next_state, waitHelpMenuChoice, StateData, ?MENU_TOUT};
: gen_fsm
ожидает, что waitHelpMenuChoice
будет в модуле menus_fsm
, что возвращает меня к тому, с чего мы начали.
Я попытался заменить проблемную строку на
{next_state, fun help_menu:waitHelpMenuChoice/2, StateData, ?MENU_TOUT};
но это просто приводит к ошибке, подобной следующей: {badarg,[{erlang,apply,[conv_fsm,#Fun<help_menu.waitHelpMenuChoice.2>,[]]}
Есть ли у кого-нибудь предложения, как это обойти?