从 gen_server 转换中返回状态
Returning State from a gen_server cast
我正在关注 http://learnyousomeerlang.com/static/erlang/kitty_gen_server.erl .
我在 temple.erl 中有我的应用程序逻辑。所有这些代码都按照我的预期进行了测试和运行。我的 land.erl 旨在成为包含 Temple 的服务器。
我的理解(请纠正任何无知)是我可以使用 gen_server 来抽象消息传递并以最小的开销跟踪状态。
我知道我的初始化函数中的第二个元组值
init([]) -> {ok, temple:new()}.
是我服务器的状态 - 在本例中,temple:new()
的 return 值。
所以我c(land)
。 (下面的代码),然后试试这个:
19> {ok, Pid2} = land:start_link().
{ok,<0.108.0>}
20> land:join(Pid2, a).
ok
当我发送加入消息时,我只是得到了原子 ok 通过阅读代码和比较我的经验 运行 kitty_gen_server,我认为状态已正确更新为值temple:join(Temple, Name)
,但 ok 原子是来自
的响应值
handle_call({join, Name}, _From, Temple) ->
{reply, ok, temple:join(Temple, Name)};
如何使用 temple:join(Temple, Name) 更新我的状态,然后将此值 return 发送给客户端?我不想调用同一个函数两次,例如
handle_call({join, Name}, _From, Temple) ->
{reply, temple:join(Temple, Name), temple:join(Temple, Name)};
所以看着小猫_gen_server我试过了
handle_call({join, Name}, _From, Temple) ->
[{reply, JoinedTemple, JoinedTemple} || JoinedTemple <- temple:join(Temple, Name)];
当我尝试此操作并显示有关语法错误的消息时,函数子句崩溃了 ||,然后我发现这仅适用于列表推导..
如何计算 temple:join(Temple, Name)]
和 return 的值给 land:join 的调用者并更新 Land 的状态?
-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}.
您可以将新状态存储在一个变量中,然后 return 一个包含该变量两次的元组:
handle_call({join, Name}, _From, Temple) ->
NewTemple = temple:join(Temple, Name),
{reply, NewTemple, NewTemple};
我正在关注 http://learnyousomeerlang.com/static/erlang/kitty_gen_server.erl .
我在 temple.erl 中有我的应用程序逻辑。所有这些代码都按照我的预期进行了测试和运行。我的 land.erl 旨在成为包含 Temple 的服务器。
我的理解(请纠正任何无知)是我可以使用 gen_server 来抽象消息传递并以最小的开销跟踪状态。
我知道我的初始化函数中的第二个元组值
init([]) -> {ok, temple:new()}.
是我服务器的状态 - 在本例中,temple:new()
的 return 值。
所以我c(land)
。 (下面的代码),然后试试这个:
19> {ok, Pid2} = land:start_link().
{ok,<0.108.0>}
20> land:join(Pid2, a).
ok
当我发送加入消息时,我只是得到了原子 ok 通过阅读代码和比较我的经验 运行 kitty_gen_server,我认为状态已正确更新为值temple:join(Temple, Name)
,但 ok 原子是来自
handle_call({join, Name}, _From, Temple) ->
{reply, ok, temple:join(Temple, Name)};
如何使用 temple:join(Temple, Name) 更新我的状态,然后将此值 return 发送给客户端?我不想调用同一个函数两次,例如
handle_call({join, Name}, _From, Temple) ->
{reply, temple:join(Temple, Name), temple:join(Temple, Name)};
所以看着小猫_gen_server我试过了
handle_call({join, Name}, _From, Temple) ->
[{reply, JoinedTemple, JoinedTemple} || JoinedTemple <- temple:join(Temple, Name)];
当我尝试此操作并显示有关语法错误的消息时,函数子句崩溃了 ||,然后我发现这仅适用于列表推导..
如何计算 temple:join(Temple, Name)]
和 return 的值给 land:join 的调用者并更新 Land 的状态?
-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}.
您可以将新状态存储在一个变量中,然后 return 一个包含该变量两次的元组:
handle_call({join, Name}, _From, Temple) ->
NewTemple = temple:join(Temple, Name),
{reply, NewTemple, NewTemple};