2012-04-05 57 views
0

我們有一個相當大的USSD應用程序,它使用Erlang的gen_fsm模塊來管理菜單選項。將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/1waitHelpMenuChoice/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>,[]]}

任何人都不會有如何解決這個問題有什麼建議?

回答

0

我設法找到解決我自己的問題。如果這看起來很明顯,那可能是因爲我對Erlang有點新鮮。

我向模塊menus_fsm添加了一個新函數wait_for_menu_response/2,它代表其他模塊處理狀態轉換。

-module(menus_fsm), 
-export([wait_for_menu_response/2]). 
% ...snip... 
wait_for_menu_response(Params, {Function, StateData}) -> 
    Function(Params, StateData). 

然後help_menu模塊進行如下變更:

-module(help_menu).  
% ...snip... 

help_menu(StateData) -> 
    menus_fsm:send_menu(StateData, "Please Select:\n1. Option 1\n2. Option 2"), 
    {next_state, wait_for_menu_response, {fun waitHelpMenuChoice/2, StateData}, ?MENU_TOUT}. 

waitHelpMenuChoice(Params, StateData) -> 
    io:format("Got Help menu response: ~p", [Params]), 
    menus_fsm:doTerminate(ok,"Help Menu", StateData). 

所以gen_fsm住宿時,它調用wait_for_menu_response,但wait_for_menu_response現在可以自由地調用help_menu:waitHelpMenuChoice/2menus_fsm模塊內。 help_menu:waitHelpMenuChoice/2不需要以任何方式進行修改。

其實,在我的最終版本中,menus_fsm:send_menu功能進行了修改,接受fun waitHelpMenuChoice/2作爲其第三個參數,從而使help_menu功能可以簡化爲:

help_menu(StateData) -> 
    menus_fsm:send_menu(StateData, "Please Select:\n1. Option 1\n2. Option 2", 
     fun waitHelpMenuChoice/2). 

,但我覺得我上面的解釋說明的想法更好。

相關問題