2016-09-16 75 views
0

我從Learn you some erlang for great good複製gen_server實現代碼,並創建一個名爲kitty_gen_server.erl的文件。然後我跑在Erlang的外殼下面的命令:在Erlang R19中實現gen_server

$ erl 
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] 

Eshell V8.0.2 (abort with ^G) 
1> c(kitty_gen_server). 
{ok,kitty_gen_server} 
2> P = kitty_gen_server:start_link(). 
{ok,<0.64.0>} 
3> kitty_gen_server:close_shop(P). 
** exception exit: {{function_clause, 
         [{gen,do_for_proc, 
          [{ok,<0.64.0>},#Fun<gen.0.62797829>], 
          [{file,"gen.erl"},{line,253}]}, 
         {gen_server,call,2,[{file,"gen_server.erl"},{line,200}]}, 
         {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]}, 
         {shell,exprs,7,[{file,"shell.erl"},{line,686}]}, 
         {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]}, 
         {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]}, 
        {gen_server,call,[{ok,<0.64.0>},terminate]}} 
    in function gen_server:call/2 (gen_server.erl, line 204) 
4> 

我相信代碼爲learn you some erlang for greate good正確的下載,但我不知道爲什麼不能EXCUTE。

我的系統是OS X 10.11,二郎19

這下面是代碼:

-module(kitty_gen_server). 
-behaviour(gen_server). 

-export([start_link/0, order_cat/4, return_cat/2, close_shop/1]). 
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, 
     terminate/2, code_change/3]). 

-record(cat, {name, color=green, description}). 

%%% Client API 
start_link() -> 
    gen_server:start_link(?MODULE, [], [{debug,[trace]}]). 

%% Synchronous call 
order_cat(Pid, Name, Color, Description) -> 
    gen_server:call(Pid, {order, Name, Color, Description}). 

%% This call is asynchronous 
return_cat(Pid, Cat = #cat{}) -> 
    gen_server:cast(Pid, {return, Cat}). 

%% Synchronous call 
close_shop(Pid) -> 
    gen_server:call(Pid, terminate). 

%%% Server functions 
init([]) -> {ok, []}. %% no treatment of info here! 

handle_call({order, Name, Color, Description}, _From, Cats) -> 
    if Cats =:= [] -> 
     {reply, make_cat(Name, Color, Description), Cats}; 
     Cats =/= [] -> 
     {reply, hd(Cats), tl(Cats)} 
    end; 
handle_call(terminate, _From, Cats) -> 
    {stop, normal, ok, Cats}. 

handle_cast({return, Cat = #cat{}}, Cats) -> 
    {noreply, [Cat|Cats]}. 

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

terminate(normal, Cats) -> 
    [io:format("~p was set free.~n",[C#cat.name]) || C <- Cats], 
    ok. 

code_change(_OldVsn, State, _Extra) -> 
    %% No change planned. The function is there for the behaviour, 
    %% but will not be used. Only a version on the next 
    {ok, State}. 

%%% Private functions 
make_cat(Name, Col, Desc) -> 
    #cat{name=Name, color=Col, description=Desc}. 

回答

4

kitty_gen_server:start_link/0上你在P直接存儲成功返回一個元組{ok, Pid},使你的下一個電話通過{ok, Pid}kitty_gen_server:close_shop/1而不是隻是Pid。您需要使用模式匹配才能將Pid存儲在P中:

1> c(kitty_gen_server). 
{ok,kitty_gen_server} 
2> {ok, P} = kitty_gen_server:start_link(). 
{ok,<0.64.0>} 
3> kitty_gen_server:close_shop(P). 
ok