[erlang-questions] pattern matching registered name

29 views
Skip to first unread message

Edmund Sumbar

unread,
May 20, 2013, 1:12:22 PM5/20/13
to erlang-q...@erlang.org
Hello,

I'm new to erlang and am perplexed by the use of registered names when they are passed as function parameters and subsequently used in pattern matching.

For example (taken from Programming Erlang 2/ed by Joe Armstrong),

-module(kvs).
-export([start/0, rpc/1]).

start() -> register(kvs, spawn(fun() -> loop() end)).

rpc(Q) ->
  kvs ! {self(), Q},
  receive
    {kvs, Reply} ->
      Reply
  end.

loop() ->
  receive
    {From, {store, Key, Value}} ->
      put(Key, {ok, Value}),
      From ! {kvs, true},
      loop();
    {From, {lookup, Key}} ->
      From ! {kvs, get(Key)},
      loop()
  end.

This module works as expected.

$ erl
Erlang R16B (erts-5.10.1) [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Eshell V5.10.1  (abort with ^G)
1> c(kvs).
{ok,kvs}
2> kvs:start().
true
3> kvs:rpc({store, name, "Joe"}).
true
4> kvs:rpc({lookup, name}).
{ok,"Joe"}

Then, I modify the code to remove the registered name.

-module(kvsx).
-export([start/0, rpc/2]).

start() -> spawn(fun() -> loop() end).

rpc(Pid, Q) ->
  Pid ! {self(), Q},
  receive
    {Pid, Reply} ->
      Reply
  end.

loop() ->
  receive
    {From, {store, Key, Value}} ->
      put(Key, {ok, Value}),
      From ! {self(), true},
      loop();
    {From, {lookup, Key}} ->
      From ! {self(), get(Key)},
      loop()
  end.

The modified module also works as expected.

$ erl
Erlang R16B (erts-5.10.1) [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Eshell V5.10.1  (abort with ^G)
1> c(kvsx).
{ok,kvsx}
2> Pid = kvsx:start().
<0.40.0>
3> kvsx:rpc(Pid, {store, name, "Joe"}).
true
4> kvsx:rpc(Pid, {lookup, name}).
{ok,"Joe"}

However, when I register a name for Pid and pass it to the function, the process hangs.

5> register(abc, Pid).
true
6> whereis(abc).
<0.40.0>
7> kvsx:rpc(abc, {lookup, name}).
^G
User switch command
 --> q

As a newcomer to the language (but with decades of programming experience), I'm confused. Can someone explain registered names and when/where they can be used.

Ed

James Aimonetti

unread,
May 20, 2013, 1:47:30 PM5/20/13
to erlang-q...@erlang.org
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
> _______________________________________________ erlang-questions
> mailing list erlang-q...@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>

rpc/2 expects the first arg into the function to be the first element
in the response tuple.
The loop/0 uses self(), which always returns a pid(), not the
registered name.
So you call rpc with an atom, and receive a tuple with a pid(). Those
don't match.
Your call to rpc/2 hangs because the selective receive in rpc/2 never
matches (and you have no timeout clause).

- --
James Aimonetti
Distributed Systems Engineer / DJ MC_

2600hz | http://2600hz.com
sip:ja...@2600hz.com
tel: 415.886.7905
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBAgAGBQJRmmGyAAoJENc77s1OYoGgjYkH/jT0bUtnghdmbNo8w0wQnqhL
sRSVuh9wKRLTuPf4x/fyCBHBEC7g6Ii+i9Xdnyc7EnaCfI7vEAx8IRmNJiMnh/Rx
9P1P+48hQmkTjRqj1aBfPR5O0EqezGB/72oPxFK5lN8hLVg0+FOjvRjF2FVezQEt
9gv5kbu7ORla9NJK+9CzGj8pUlx0CQ5ba7pXIU0ib00hf6DA3g8rJmpbS1Fe7+6i
5eYJLvh0/m6F8YjGtrdYIEfCfey7assHMgOIZ+iC2QjcbnqWPZHCbuhsPUz0LbMu
BQOOn3/8NAbstOOMzW7LHjCJ80yLJX9HMHn+bvORTaFVIDy1kUxhDJSUDDP7mSs=
=iAES
-----END PGP SIGNATURE-----
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Yogish Baliga

unread,
May 20, 2013, 1:48:51 PM5/20/13
to Edmund Sumbar, Erlang Questions
When you call rpc(abc, blah), Pid = abc. In your rpc(...) code you are waiting for
{abc, Resp} in receive loop.


Edmund Sumbar

unread,
May 20, 2013, 2:47:05 PM5/20/13
to erlang-q...@erlang.org

On Mon, May 20, 2013 at 11:47 AM, James Aimonetti <ja...@2600hz.com> wrote:
rpc/2 expects the first arg into the function to be the first element
in the response tuple.
The loop/0 uses self(), which always returns a pid(), not the
registered name.
So you call rpc with an atom, and receive a tuple with a pid(). Those
don't match.
Your call to rpc/2 hangs because the selective receive in rpc/2 never
matches (and you have no timeout clause).

What's confusing is that the atom apparently resolves into a pid() in the send expression of kvsx:rpc/2 (adding io:format("reg name = ~p~n", [whereis(abc)]) to the function returns the pid()), but not in the pattern tuple of the receive expression.

Anyway, thanks for the replies James and Yogish.

Ed

James Aimonetti

unread,
May 20, 2013, 3:34:52 PM5/20/13
to erlang-q...@erlang.org
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

> _______________________________________________ erlang-questions
> mailing list erlang-q...@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>

You could change rpc/2:

rpc(Name, Q) when is_atom(Name) ->
rpc(whereis(Name), Q);
rpc(Pid, Q) when is_pid(Pid) ->
Pid ! {self(), Q},
receive
{Pid, Reply} ->
Reply
end.

This will crash the caller if Name isn't registered, FYI.

- --
James Aimonetti
Distributed Systems Engineer / DJ MC_

2600hz | http://2600hz.com
sip:ja...@2600hz.com
tel: 415.886.7905
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBAgAGBQJRmnrcAAoJENc77s1OYoGgF1EH/Ajv0qTcrUEK+NL4kNJ7w8rQ
G6hdnnpm6231XA6h9MbmW0jph5nYdAo5PBeF0QBK3XyuVOUw1AvZv8PcqTTHmsKc
K0RbZFip7mfNWXFa3wPufg1K7cZ8F5yG4k5BB+PpHSRfnh+UVs7z+qVNeXKXBWp2
OClbohj6BqzuRR8udb+k73Bz1uwsIqDDWTSEtBpJ4YQJwSmTBjlHKIJ6wnEi5yl3
VXFdM+/KKBN0coO3TOWOvTt4soN2AqLKSKL7XfNs91FyJvAL/nJ1YderAY2Q9MY8
MZCLxF/Nsjjm4OxlabTEyMP/wnKwmNNvKmjx7Adx0ve+SoZbjayD32zl5goIQU8=
=IwqX

Bob Ippolito

unread,
May 20, 2013, 3:55:35 PM5/20/13
to James Aimonetti, erlang-questions
This strategy is also used by OTP in gen.erl (the plumbing for gen_server, gen_fsm, gen_event, …). 

Richard A. O'Keefe

unread,
May 20, 2013, 9:47:33 PM5/20/13
to Edmund Sumbar, erlang-q...@erlang.org

In a Who ! What send, Who may be a pid or a registered name.
In a pattern match, registered names do not match pids; they are
just literal atoms.

Robert Virding

unread,
May 21, 2013, 3:59:13 PM5/21/13
to Richard A. O'Keefe, erlang-q...@erlang.org
Yes, the registered name is just an atom, it is the '!' which interprets this atom as the registered name of a process, if it exists. It is still just a normal atom, the difference is in the interpretation.
Reply all
Reply to author
Forward
0 new messages