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 ].