% places.erl -module(places). -author('Alan G. Labouseur'). -define(else, true). % -- This is to make the if statements (somewhat) readable. %-------- % Public %-------- -export([start/0, p1/0]). % Note that p2/0 is not exported. start() -> io:fwrite("~nstart() [pid ~w] has... started.~n~n", [self()]), P1pid = spawn(places, p1, []), % Note the different syntax compared to ag_server. Requires p1/0 to be public. % We want to publish this process in Erlang's Process Dictionary. % Before we do that, we need to un-register it if it's already been registered. SomePlace = whereis(place1), if (SomePlace /= undefined) -> % "not undefined" = "is defined" (This is horrible, I know.) unregister(place1); ?else -> % The proccess was NOT already published/registered, so we don't really want to do anything here. true % This is dumb, but I couldn't think of a better "no-op". end, % Publish this process in Erlang's Process Dictionary. register(place1, P1pid), % Now we can refer to it by atom place1 rather than it's pid when sending. place1 ! {self(), someRequest}, receive {P1pid, Response1} -> % This waits for a response from P1pid, which is place1. Can we use place1 somehow? io:fwrite("start() [pid ~w] received a response from pid ~w:~n", [self(), P1pid]), io:fwrite(" ~s~n", [Response1]) end, OtherPlace = whereis(place2), if (OtherPlace /= undefined) -> % "not undefined" = "is defined" (This is horrible, I know.) unregister(place2); ?else -> % The proccess was NOT already published/registered, so we don't really want to do anything here. true % This is dumb, but I couldn't think of a better "no-op". end, % Spawn and register (like in our book on page 214) at the same time. register(place2, spawn(fun() -> p2() end)), % This spawn syntax does NOT require p2/0 to be exported. % We can refer to it by the atom place2 rather than it's pid when sending as long as we're consistent about that. place2 ! {self(), anotherRequest}, receive {place2, Response2} -> io:fwrite("start() [pid ~w] received a response from pid ~w:~n", [self(), place2]), % (consistent) io:fwrite(" ~s~n", [Response2]) end. % This is spawned from start() in a manner that requires it to be public. p1() -> receive {FromPid, Request} -> io:fwrite("p1() [pid ~w] received request [~w] from pid ~w.~n", [self(), Request, FromPid]), Response = io_lib:format("This text is p1()'s [pid ~w's] response to pid ~w.~n", [self(), FromPid]), FromPid ! {self(), Response}, p1() end. %-------- % Private %-------- % This is spawned from start() in a manner that allows it to be private, % but still "seen" when messages are sent to it. p2() -> receive {FromPid, Request} -> io:fwrite("p2() [pid ~w] received request [~w] from pid ~w.~n", [self(), Request, FromPid]), Response = io_lib:format("This text is p2()'s [pid ~w's] response to pid ~w.~n", [self(), FromPid]), FromPid ! {place2, Response}, p2() end.