1> bank_server3:create_account(name1, 1000).
true
2> name1 ! check.
Current money is: 1000
check
3> erlang:send(name1, check).
Current money is: 1000
check
4> erlang:send(name1, abcd).
handle_info: abcd
abcd
Yearly Payment: 940 -> 880
5> gen_server:cast(name1, msg1).
handle_cast: msg1
ok
6> gen_server:cast(name123, msg1).
ok
7> name123 ! check.
** exception error: bad argument
in operator !/2
called as name123 ! check
Yearly Payment: 880 -> 820
8> gen_server:call(name1, msg1).
handle_call: msg1
ok
9> erlang:send(name1, stop1).
Receive STOP1
terminate: "Force STOP"
stop1
10>
=ERROR REPORT==== 15-Jan-2015::09:02:35 ===
** Generic server <0.34.0> terminating
** Last message in was stop1
** When Server state == 820
** Reason for termination ==
** "Force STOP"
Eshell V5.10.4 (abort with ^G)
1> bank_server3:create_account(name2, 1000).
true
2> name2 ! stop2.
Receive STOP2
terminate: normal
stop2
-module(bank_server3). -behaviour(gen_server). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([create_account/2]). -define(I(F), io:format(F++"~n", [])). -define(I(F, A), io:format(F++"~n", A)). % -------------------------------------------------------------------- % API % -------------------------------------------------------------------- %%'银行开户,并存入初始金额 -spec create_account(Name, Money) -> any() when Name :: atom(), Money :: integer(). create_account(Name, Money)-> %% gen_server:start(Mod, Args, Options) {ok, Pid} = gen_server:start(?MODULE, [Money], []), %% 假设年费为10 Pid ! {yearly, 60}, erlang:register(Name, Pid). % -------------------------------------------------------------------- % Callback % -------------------------------------------------------------------- init([Money]) -> {ok, Money}. handle_call(check, _From, Money) -> {reply, Money, Money}; handle_call(Request, _From, State) -> ?I("handle_call: ~p", [Request]), Reply = ok, {reply, Reply, State}. handle_cast(Msg, State) -> ?I("handle_cast: ~p", [Msg]), {noreply, State}. %%'存钱 handle_info({deposit, AddMoney}, Money) -> NewMoney = Money + AddMoney, ?I("deposit money: ~w -> ~w", [Money, NewMoney]), {noreply, NewMoney}; %%. %%'取钱(可透支) handle_info({cash1, SubMoney}, Money) -> NewMoney = Money - SubMoney, ?I("deposit money: ~w -> ~w", [Money, NewMoney]), {noreply, NewMoney}; %%. %%'取钱(不可透支) handle_info({cash2, SubMoney}, Money) -> NewMoney = Money - SubMoney, case NewMoney > 0 of true -> %% 支取成功 ?I("deposit money: ~w -> ~w", [Money, NewMoney]), {noreply, NewMoney}; false -> %% 支取失败 提示余额不足 ?I("Insufficient balance, current money is ~w", [Money]), {noreply, Money} end; %%. %%'扣年费(这里假设10秒为一年) handle_info({yearly, Payment}, Money) -> Year = case get(year) of undefined -> put(year, 0), 0; Y -> YY = Y + 1, put(year, YY), YY end, erlang:send_after(60 * 1000, self(), {yearly, Payment}), Reply = if Money =< 0 -> %% 没有钱可以扣 Money; Year =:= 0 -> %% 还不到一年,不用扣 Money; true -> NewMoney = Money - Payment, case NewMoney > 0 of true -> %% 扣费成功 ?I("Yearly Payment: ~w -> ~w", [Money, NewMoney]), NewMoney; false -> %% 余额不足以扣年费,则扣到0为止 ?I("Yearly Payment: ~w -> ~w", [Money, 0]), 0 end end, {noreply, Reply}; %%. %%'查询 handle_info(check, Money) -> ?I("Current money is: ~w", [Money]), {noreply, Money}; handle_info({From, check}, Money) -> %% ?I("Send result to: ~w", [From]), From ! {self(), Money}, {noreply, Money}; %%. handle_info(stop1, Money) -> ?I("Receive STOP1"), Reason = "Force STOP", {stop, Reason, Money}; handle_info(stop2, Money) -> ?I("Receive STOP2"), Reason = normal, {stop, Reason, Money}; handle_info(Info, State) -> ?I("handle_info: ~p", [Info]), {noreply, State}. terminate(Reason, _State) -> ?I("terminate: ~p", [Reason]), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}.