When should I use process-wide dictionary and when should my process state be in the parameters of the loop function?
This:
loop() ->
receive
{From, subscribe} ->
put(listeners, [From|get(listeners)]),
?MODULE:loop()
end.
Or this:
loop(Listeners) ->
receive
{From, subscribe} ->
?MODULE:loop([From|Listeners])
end.
?
Parameters to the loop function has the benefit of being explicit in that nothing outside it can change the parameters (unless you're doing strange magic bouncing on another function like a trampoline), but state tends to add up, and the parameters with them.
How about a dict as a parameter? Best of both worlds or worst of both worlds?
I would suggest you to use a record to store your loop data. That way if you ever need to add a new "variable" to your loop data all you have to do is add it to the record, without touching any of your clauses. Dict would only be a better choice if your "keys" recently change, which is unlikely in the case of loop data.
-record(state, {
listeners = [],
new_var = undefined,
new_var2 = ""
...
}).
init() ->
loop(#state{}).
loop(State) ->
receive
{From, subscribe} ->
loop(State#state{listeners = [From|State#state.listeners]});
somethingelse ->
do_nothing(),
loop(State)
end.
The main disadvantage of using the process dictionary relates to the possible side-effects: when you start using the process dictionary liberally, you'll have more difficulty tracking possible side-effects.
For example, let's say you are in function "X" and start pulling data from the process dictionary, then you are effectively working against the functional nature of Erlang.
But hey, at some point you'll need to have access to a bigger data store, won't you? The point is: try to isolate as much as possible access to the process dictionary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With