SICP/exercise_3_3.erl
author Eung-ju PARK <eungju@gmail.com>
Wed Nov 28 21:46:40 2007 +0900 (11 months ago)
changeset 56 1e8b8d09840a
parent 55f1c40080992a
permissions -rw-r--r--
Added password protection.
     1 -module(exercise_3_3).
     2 -compile(export_all).
     3 -include_lib("eunit/include/eunit.hrl").
     4 
     5 account(Balance) ->
     6     receive
     7 	{withdraw, From, Amount} when Balance < Amount ->
     8 	    From ! {error, underflow},
     9 	    account(Balance);
    10 	{withdraw, From, Amount} ->
    11 	    account(From ! Balance - Amount);
    12 	{deposit, From, Amount} ->
    13 	    account(From ! Balance + Amount);
    14 	{_, From, _Amount} ->
    15 	    From ! {error, unknown_request},
    16 	    account(Balance)
    17     end.
    18 
    19 make_account(Balance, Password) ->
    20     Pid = spawn(?MODULE, account, [Balance]),
    21     fun(Action, P) when Password =:= P ->
    22 	    fun(Amount) ->
    23 		    Pid ! {Action, self(), Amount},
    24 		    receive
    25 			{error, Why} ->
    26 			    throw(Why);
    27 			Result ->
    28 			    Result
    29 		    end
    30 	    end;
    31        (_Action, _P) ->
    32 	    fun(_Amount) ->
    33 		    throw(incorrect_password)
    34 	    end
    35     end.
    36 
    37 account_test_() ->
    38     A = make_account(100, secret_password),
    39     [?_assertMatch(60, (A(withdraw, secret_password))(40)),
    40      ?_assertMatch(80, (A(deposit, secret_password))(20)),
    41      ?_assertMatch(underflow, catch((A(withdraw, secret_password))(100))),
    42      ?_assertMatch(unknown_request, catch((A(robe, secret_password))(20))),
    43      ?_assertMatch(incorrect_password, catch((A(withdraw, wrong_password))(20)))].