[erlang-questions] If you are homesick for object.selector

José Valim jose.valim@REDACTED
Fri Jan 25 17:34:21 CET 2013

Since there has been some discussion about "real" code, I can provide some.
The extract below comes the latest project I am working on and it was
extracted from a gen server. Gen servers are spawned by a simple one by one
supervisor and each represents a building. The gen server needs to keep
track of:

1. How many people (i.e. users) are in the building overall;

2. And how many of those users are on each level. Users in the same
building can comunicate with each other via codes and each code is tied to
a socket pid;

3. The users dict in state contains a user_id -> #user relation. And the
levels dict in state contains a level_id -> [user_id] relation (I am
keeping this as a reverse index instead of a levels list inside each user
because this is how I access this data);

    -record(state, { levels=dict:new(), users=dict:new(), review=30000,
company_id=undefined }).
    -record(user, { codes=dict:new() }).
    -record(code, { pid=nil, counter=0 }).

There is more information in the system but that is in a database because
the gen server does not care about it. The state record is what is passed
around gen server callbacks.

As Loïc previously said, I like to treat all the information above as data.
If the user gets a new code, I would like to simply add it to the codes
dictionary in the user. This is how it looks like:

    User1 = User#user{ codes=dict:store(Code, #code{pid=Pid},
User#user.codes) },
    Users1 = dict:store(UserId, User1, Users),
    { reply, ok, State#state{users=Users1} }.

And that is because the snippet above is *not* showing how the User, Users
and Code variables were retrieved. Indeed, it could be much better and we
don't even need to compare with PHP, which contains mutable data
structures. For instance, Clojure provides an assoc_in[1] (and related
functions) that would allow me to write all of this as:

    { reply, ok, assoc_in(State, [users, UserId, codes], Code,
#code{pid=Pid}) }

Which is similar to what the kvc project does. Others have mentioned lenses
as well. My point is that it seems to be a common issue and others seem to
be looking for (or have found) a streamlined solution, which they can
present and introduce to developers using and learning the language.

[1]: http://clojuredocs.org/clojure_core/1.2.0/clojure.core/assoc-in

 *José Valim*
Skype: jv.ptec
Founder and Lead Developer
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130125/eeed9642/attachment.htm>

More information about the erlang-questions mailing list