2016-11-28 15 views
1

Я следую за http://learnyousomeerlang.com/static/erlang/kitty_gen_server.erl.Возвращающееся состояние из gen_server cast

У меня есть моя логика приложения внутри temple.erl. Весь этот код протестирован & работает так, как я ожидаю. Мой land.erl предназначен для сервера, который содержит Храм.

Мое понимание (исправьте любое незнание) заключается в том, что я могу использовать gen_server для абстрактного прохождения сообщений и отслеживания состояния с минимальными накладными расходами.

Я понимаю, что второй tuplevalue в моей инициализации функции

init([]) -> {ok, temple:new()}. это состояние моего сервера - в этом случае, возвращаемое значение temple:new().

So I c(land). (Код ниже), и попробуйте следующее:

19> {ok, Pid2} = land:start_link(). 
{ok,<0.108.0>} 
20> land:join(Pid2, a). 
ok 

и я просто получить атом нормально, когда я отправить сообщение присоединиться От чтения коды и сравнивая свой опыт работы в kitty_gen_server, я думаю, что государство правильно обновляется значение temple:join(Temple, Name), но нормально атом значение ответа от

handle_call({join, Name}, _From, Temple) -> 
{reply, ok, temple:join(Temple, Name)}; 

как я могу обновить мое состояние с храмом присоединиться (храм, имя), а затем возвращает это значение клиенту? Я не хочу дважды называть одну и ту же функцию.

handle_call({join, Name}, _From, Temple) -> 
{reply, temple:join(Temple, Name), temple:join(Temple, Name)}; 

Так, глядя на kitty_gen_server я попытался

handle_call({join, Name}, _From, Temple) -> 
[{reply, JoinedTemple, JoinedTemple} || JoinedTemple <- temple:join(Temple, Name)]; 

и я получаю аварию дизъюнкции функции, когда я пытаюсь это с сообщением об ошибке синтаксиса ||, а затем я вижу, что это только для списка понимание.

как я могу вычислить значение temple:join(Temple, Name)] и вернуться к получателю земли: присоединяйтесь и обновите состояние земли?

-module(land). 
-behaviour(gen_server). 

-export([start_link/0, join/2, input/3, fight/1]). 
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, 
     terminate/2, code_change/3]). 

start_link() -> 
    gen_server:start_link(?MODULE, [], []). 

join(Pid, Name) -> 
    gen_server:call(Pid, {join, Name}). 

input(Pid, Action, Target) -> 
    gen_server:call(Pid, {input, Action, Target}). 

fight(Pid) -> 
    gen_server:call(Pid, fight). 

init([]) -> {ok, temple:new()}. 

handle_call({join, Name}, _From) -> 
    {reply, ok, temple:join(Name)}. 
handle_call({join, Name}, _From, Temple) -> 
    {reply, temple:join(Temple, Name), temple:join(Temple, Name)}; 
handle_call(terminate, _From, Temple) -> 
    {stop, normal, ok, Temple}. 

handle_info(Msg, Temple) -> 
    io:format("Unexpected message: ~p~n",[Msg]), 
    {noreply, Temple }. 

terminate(normal, Temple) -> 
    io:format("Temple bathed in blood.~p~n", [Temple]), 
    ok. 

code_change(_OldVsn, State, _Extra) -> 
    {ok, State}. 

handle_cast(_, Temple) -> 
    {noreply, Temple}. 

ответ

3

Вы можете сохранить новое состояние в переменной, а затем возвращает кортеж, содержащий эту переменную дважды:

handle_call({join, Name}, _From, Temple) -> 
    NewTemple = temple:join(Temple, Name), 
    {reply, NewTemple, NewTemple}; 
+0

Doh, конечно! Спасибо! – quantumpotato