[erlang-questions] How to do counters?

Richard O'Keefe <>
Tue Jun 30 01:46:06 CEST 2009


On Jun 30, 2009, at 4:09 AM, Jarrod Roberson wrote:
> That doesn't "smell" right to me. Is there a better way to create
> "instances" of these counter module examples?

Just have a counter:new() function that returns you the PID
of a new process.

	-module(counter).
	-export([new/0, read/1, up/1, down/1, reset/1]).

	new() ->
	    {counter,spawn(fun () -> loop(0) end)}.

	loop(N) ->
	    receive {Msg,Sender} ->
	        Sender ! {self(), N},
	        loop(case Msg
		       of read -> N
		        ; up   -> N + 1
		        ; down -> N - 1
		        ; reset-> 0
		     end)
	    end.

	read(Counter) ->
	    ipc(Counter, read).

	up(Counter) ->
	    ipc(Counter, up).

	down(Counter) ->
	    ipc(Counter, down).

	reset(Counter) ->
	    ipc(Counter, reset).

	ipc({counter,Pid}, Msg) when is_pid(Pid) ->
	    Pid ! {Msg,self()},
	    receive {Pid,Result} -> Result end.

Bind the result of a call to counter:new() to a variable,
and use that variable.  Example:

1> c(counter).
{ok,counter}
2> C1 = counter:new().
{counter,<0.38.0>}
3> C2 = counter:new().
{counter,<0.40.0>}
4> counter:up(C1).
0
5> counter:read(C1).
1
6> counter:read(C2).
0

As a general rule, don't register a process unless there is
a REALLY good reason to do so.




More information about the erlang-questions mailing list