2016-02-16 95 views
1

LYSE之後,我試着用gen_server重新實現kitty_server2。但由於某些原因,我得到這個錯誤:我的gen_server實現有什麼問題?

37> Cat1 = kitty_server3:order_cat(Pid, carl, brown, 2). 
Ordeirng cat!** exception exit: {{function_clause, 
         [{gen,do_for_proc, 
          [{ok,<0.162.0>},#Fun<gen.0.132519590>], 
          [{file,"gen.erl"},{line,252}]}, 
         {gen_server,call,2,[{file,"gen_server.erl"},{line,200}]}, 
         {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,673}]}, 
         {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,438}]}, 
         {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.162.0>},{order,carl,brown,2}]}} 
    in function gen_server:call/2 (gen_server.erl, line 204) 

我似乎已經實現了所有必需的回調,我真的不能告訴什麼錯誤意味着。是否說我錯過了一個回調?因爲它似乎甚至沒有調用相關handle_call

下面是完整的服務器實現:

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

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

start() -> gen_server:start(?MODULE, {[], 0}, []). 
start_link() -> gen_server:start_link(?MODULE, {[], 0}, []). 

%%% Client api 
%% Asynchronous 
return_cat(Pid, Cat = #cat{}) -> gen_server:cast(Pid, {return, Cat}). 

%% Synchronous call 
order_cat(Pid, Name, Color, Price) -> 
    io:format("Ordeirng cat!"), 
    gen_server:call(Pid, {order, Name, Color, Price}). 

sell_cat(Pid, Cat, Price) -> 
    gen_server:call(Pid, {sell, Cat, Price}). 

close_shop(Pid) -> gen_server:stop(Pid). 

%%% Callback functions 
init(State) -> {ok, State}. 

%%% Server functions 
%% Synchronous callbacks 
handle_call({order, Name, Color, Price}, _From, {Cats, Money}) -> 
    io:format("Handling cat order.."), 
    if Cats =:= [] -> 
     io:format("1.."), 
     {reply, make_cat(Name, Color, Price), {Cats, Money + Price}}; 
     Cats =/= [] -> % empty the stock 
     io:format("2.."), 
     {reply, hd(Cats), {tl(Cats), Money + Price}} 
    end; 

handle_call({sell, Cat, Price}, _From, {Cats, Money}) -> 
    if Money >= Price -> 
     {reply, Price, {[Cat|Cats], Money - Price}}; % pay the customer! 
     Money < Price -> 
     {reply, 0, {Cats, Money}} % pay nothing we are poor! 
    end. 

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

%% Terminate callback 
terminate(_Reason, {Cats, Money}) -> 
    release_the_cats(Cats, Money). 

%% Code change callback 
code_change(_OldVsn, State, _Extra) -> 
    {ok, State}. 

%% Handle unexpected messages callback 
handle_info(Info, State) -> 
    io:format("Unexpected message: ~w", [Info]), 
    {noreply, State}. 

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

release_the_cats(Cats, Money) -> 
    io:format("Made $~w~n", [Money]), 
    [io:format("~p was set free.~n",[C#cat.name]) || C <- Cats]. 

任何提示嗎?

+1

除了添加自己的'io:format'調用來幫助你調試,只需要改變'gen_server:start'調用的最後一個參數來啓用['sys'](http://erlang.org/doc/man /sys.html)跟蹤,如下所示:'gen_server:start(?MODULE,{[],0},[{debug,[trace]}])。'或者你可以調用'sys:trace(Pid,true) 。'在調用'{ok,Pid} = kitty_server3:start()。'後,在shell中假設服務器啓動正常。 –

回答

2

這工作完全正常,我:

Eshell V7.2.1 (abort with ^G) 
1> l(kitty_server3). 
{module,kitty_server3} 
2> {ok, Pid} = kitty_server3:start(). 
{ok,<0.36.0>} 
3> kitty_server3:order_cat(Pid, carl, brown, 2). 
Ordeirng cat!Handling cat order..1..{cat,carl,brown,2} 
4> 

也許你已經做出了一些改變,並沒有正確地重新加載的模塊或您的Erlang shell有一些舊的變量綁定?

+0

我在做:'Pid = kitty_server3:start()' - 忘記它現在返回一個元組。謝謝一堆! – drozzy

相關問題