Reputation: 419
I am looking to build simple erlang logic where an actor maintains the count of how many times it was invoked.
For example, here is the actor(many actors can be possible):
-module(actor).
-export([do_work/0]).
do_work() ->
increment = increment + 1
Suppose I invoke actor (with some Pid: XYZ) 5 times, XYZ = 5 because it was executed 5 times. But in Erlang, variables are immutable. So if I do increment++
for the first run, I cannot store the new result in increment or do increment = increment + 1
. How do I maintain the count because I cannot create new variables dynamically say, increment_iteration_1 = increment + 1
and then do increment_iteration_2 = increment1 + 1
and so on.....in code for 1000 iterations?
Upvotes: 1
Views: 207
Reputation: 20993
Your question touches the main difference between Erlang and other popular languages. In order to maintain and update some state - as the counter in your example - in Erlang you need to do some specific things, which I describe below. (Other solutions, like using a database, I will skip here since I assume you want to know how to do state maintenance directly).
In Erlang what you call actor is called process. And yes, to maintain a state, you need a process. The code you presented, though named actor, is not a process. It is just a module, which means that it is just some code. To use a process you need to start it, keep it running, and communicate with it using messages. It may sound complicated, but Erlang standard library provides gen_server, which does most of the work for you.
The sample code implementing a counter with gen_server would look like that:
-module(actor).
-behaviour(gen_server).
-export([do_work/0, init/1, handle_cast/2, handle_call/3]).
do_work() ->
gen_server:cast(actor_server, do_work).
init(_Arguments) ->
{ok, 0}.
handle_cast(do_work, Counter) ->
{noreply, Counter + 1}.
handle_call(_Msg, _From, Counter) ->
{noreply, Counter}.
Now somewhere in your code you need to start your process with
gen_server:start_link({local, actor_server}, actor, [], [])
Then, whenever you call actor:do_work()
, it will increment the counter.
Few things worth mentioning are:
init
callback function is called once when your process starts. I used it here to initialise the counter.handle_call
part, not used here, provides the functionality where you can receive a reply (e.g. updated counter) from the process.More information about gen_server you will find its documentation.
Upvotes: 4