The following is a complete module to test my approach. The messaging was slightly changed.
First, the sample session:
1> c(prob8101pragmatic).
{ok,prob8101}
2> prob8101pragmatic:unittest().
[true,true,true,true,true,true,true,true]
And now the module itself:
-module(prob8101pragmatic).
-export([start/2,init_registrar/0, server/2, client/2, unittest/0]).
init_registrar() ->
register(registrar,spawn(fun() -> loop() end)).
loop() ->
receive
{register,Atom,Fun,From} ->
case whereis(Atom) of
undefined ->
register(Atom,spawn(Fun)),
From!{registered_ok,whereis(Atom)},
loop();
_Otherwise ->
From!{already_registered,whereis(Atom)},
loop()
end;
{stop, From} ->
From!{stopped,self()}
end.
server(Atom,F) ->
receive {enough,From} ->
From!{Atom, exited},
ok;
{X,From} ->
From!{Atom, F(X)},
server(Atom, F)
end.
client(Atom, Param) ->
Atom!{Param,self()},
receive {Atom,Y} ->
% io:format("received from ~p: ~p~n", [Atom,Y]),
Y
end.
start(AnAtom, Fun) ->
registrar ! {register, AnAtom, fun() -> server(AnAtom, Fun) end, self()},
receive
{Result,Newid} -> {Result,Newid}
end.
stop_registry() ->
registrar ! {stop, self()},
receive
{Result,_Rid} -> Result
end.
unittest() ->
Sq = fun(X) -> X * X end,
Qb = fun(X) -> X * X * X end,
init_registrar(),
{R_OK,_} = start(square, Sq),
{R_NO,_} = start(square, Sq),
{R_OK,_} = start(cube, Qb),
TwentyFive = client(square, 5),
SixtyFour = client(square, 8),
Nine = client(cube, 3),
C125 = client(cube, 5),
Exited = client(square, enough),
Exited = client(cube, enough),
Stopped = stop_registry(),
[ R_OK == registered_ok,
R_NO == already_registered,
TwentyFive == 25,
SixtyFour == 64,
Nine == 27,
C125 == 125,
Exited == exited,
Stopped == stopped
].
No comments:
Post a Comment