Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' of github.com:uwiger/gproc

Conflicts:
	doc/edoc-info
	doc/gproc.md
	doc/gproc_dist.md
	doc/gproc_lib.md
  • Loading branch information...
commit 9d3514d8a719079e4a34d12923b06a796067e0ca 2 parents 05cd9f8 + 2b42b5d
@uwiger uwiger authored
View
2  .gitignore
@@ -1,8 +1,8 @@
current_counterexample.eqc
deps/
-ebin/
.eunit/
*~
*/*~
+*/#*#
erl_crash.dump
gproc_dist*@*
View
1  README.md
@@ -115,5 +115,6 @@ Freiburg 2007 ([Paper available here](http://github.com/esl/gproc/blob/master/do
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_monitor.md" class="module">gproc_monitor</a></td></tr>
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_pool.md" class="module">gproc_pool</a></td></tr>
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_ps.md" class="module">gproc_ps</a></td></tr>
+<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_pt.md" class="module">gproc_pt</a></td></tr>
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_sup.md" class="module">gproc_sup</a></td></tr></table>
View
1  doc/README.md
@@ -115,5 +115,6 @@ Freiburg 2007 ([Paper available here](erlang07-wiger.pdf)).
<tr><td><a href="gproc_monitor.md" class="module">gproc_monitor</a></td></tr>
<tr><td><a href="gproc_pool.md" class="module">gproc_pool</a></td></tr>
<tr><td><a href="gproc_ps.md" class="module">gproc_ps</a></td></tr>
+<tr><td><a href="gproc_pt.md" class="module">gproc_pt</a></td></tr>
<tr><td><a href="gproc_sup.md" class="module">gproc_sup</a></td></tr></table>
View
2  doc/edoc-info
@@ -1,4 +1,4 @@
{application,gproc}.
{packages,[]}.
{modules,[gproc,gproc_app,gproc_bcast,gproc_dist,gproc_info,gproc_init,
- gproc_lib,gproc_monitor,gproc_pool,gproc_ps,gproc_sup]}.
+ gproc_lib,gproc_monitor,gproc_pool,gproc_ps,gproc_pt,gproc_sup]}.
View
7 doc/gproc.md
@@ -1479,7 +1479,7 @@ but the select patterns are transformed appropriately.
<pre><code>
-send(Key::<a href="#type-key">key()</a>, Msg::any()) -&gt; Msg
+send(Key::<a href="#type-process">process()</a> | <a href="#type-key">key()</a>, Msg::any()) -&gt; Msg
</code></pre>
<br></br>
@@ -1489,10 +1489,15 @@ send(Key::<a href="#type-key">key()</a>, Msg::any()) -&gt; Msg
Sends a message to the process, or processes, corresponding to Key.
+
If Key belongs to a unique object (name or aggregated counter), this
function will send a message to the corresponding process, or fail if there
is no such process. If Key is for a non-unique object type (counter or
property), Msg will be send to all processes that have such an object.
+
+
+Key can also be anything that the erlang:send/2, or '!' operator accepts as a process
+identifier, namely a pid(), an atom(), or `{Name::atom(), Node::atom()}`.
<a name="set_attributes-2"></a>
### set_attributes/2 ###
View
2  doc/gproc_dist.md
@@ -7,7 +7,7 @@
Extended process registry.
-__Behaviours:__ [`gen_leader`](/Users/uwiger/FL/git/gen_leader/doc/gen_leader.md).
+__Behaviours:__ [`gen_leader`](gen_leader.md).
__Authors:__ Ulf Wiger ([`ulf@wiger.net`](mailto:ulf@wiger.net)).
<a name="description"></a>
View
54 doc/gproc_pt.md
@@ -0,0 +1,54 @@
+
+
+# Module gproc_pt #
+* [Description](#description)
+* [Function Index](#index)
+* [Function Details](#functions)
+
+
+Parse transform utility for gproc users.
+__Authors:__ Ulf Wiger ([`ulf@wiger.net`](mailto:ulf@wiger.net)), Dmitry Demeshchuk ([`demeshchuk@gmail.com`](mailto:demeshchuk@gmail.com)).
+<a name="description"></a>
+
+## Description ##
+
+
+
+This module provides some closer syntactical integration for
+people who are enthusiastic gproc users.
+
+
+
+Specifically, this module transforms `Pid ! Msg` into
+`gproc:send(Pid, Msg)`, which, apart from accepting any type for
+`Pid` that `!` understands, is also able to handle a gproc "triple",
+e.g. `{n, l, Name}` or even `{p, l, Prop}` (in the latter case, the
+message may be delivered to multiple recipients).
+
+
+
+Users should be aware that parse transforms may be confusing to
+the casual reader, since they extend the semantics of possibly
+ubiquitous constructs (as is the case with this transform). Therefore,
+you should document clearly that this is happening.
+
+
+Original suggestion by Dimitry Demeschuk.<a name="index"></a>
+
+## Function Index ##
+
+
+<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#parse_transform-2">parse_transform/2</a></td><td></td></tr></table>
+
+
+<a name="functions"></a>
+
+## Function Details ##
+
+<a name="parse_transform-2"></a>
+
+### parse_transform/2 ###
+
+`parse_transform(Forms, Options) -> any()`
+
+
View
2  ebin/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
View
10 src/gproc.erl
@@ -1709,7 +1709,7 @@ give_away1({_,g,_} = Key, To) ->
goodbye() ->
process_is_down(self()).
-%% @spec (Key::key(), Msg::any()) -> Msg
+%% @spec (Key::process() | key(), Msg::any()) -> Msg
%%
%% @doc Sends a message to the process, or processes, corresponding to Key.
%%
@@ -1717,8 +1717,15 @@ goodbye() ->
%% function will send a message to the corresponding process, or fail if there
%% is no such process. If Key is for a non-unique object type (counter or
%% property), Msg will be send to all processes that have such an object.
+%%
+%% Key can also be anything that the erlang:send/2, or '!' operator accepts as a process
+%% identifier, namely a pid(), an atom(), or `{Name::atom(), Node::atom()}'.
%% @end
%%
+send(P, Msg) when is_pid(P); is_atom(P) ->
+ P ! Msg;
+send({Name, Node} = P, Msg) when is_atom(Node), is_atom(Name) ->
+ P ! Msg;
send(Key, Msg) ->
?CATCH_GPROC_ERROR(send1(Key, Msg), [Key, Msg]).
@@ -1771,7 +1778,6 @@ bcast1(Ns, {T,l,_} = Key, Msg) when T==p; T==a; T==c; T==n; T==p ->
gen_server:abcast(Ns -- [node()], gproc_bcast, {send, Key, Msg}),
Msg.
-
%% @spec (Context :: context()) -> key() | '$end_of_table'
%%
%% @doc Behaves as ets:first(Tab) for a given type of registration.
View
57 src/gproc_pt.erl
@@ -0,0 +1,57 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% @author Ulf Wiger <ulf@wiger.net>
+%% @author Dmitry Demeshchuk <demeshchuk@gmail.com>
+%%
+%% @doc Parse transform utility for gproc users.
+%%
+%% This module provides some closer syntactical integration for
+%% people who are enthusiastic gproc users.
+%%
+%% Specifically, this module transforms `Pid ! Msg' into
+%% `gproc:send(Pid, Msg)', which, apart from accepting any type for
+%% `Pid' that `!' understands, is also able to handle a gproc "triple",
+%% e.g. `{n, l, Name}' or even `{p, l, Prop}' (in the latter case, the
+%% message may be delivered to multiple recipients).
+%%
+%% Users should be aware that parse transforms may be confusing to
+%% the casual reader, since they extend the semantics of possibly
+%% ubiquitous constructs (as is the case with this transform). Therefore,
+%% you should document clearly that this is happening.
+%%
+%% Original suggestion by Dimitry Demeschuk.
+%% @end
+%%
+-module(gproc_pt).
+
+-export([parse_transform/2]).
+
+parse_transform(Forms, _Options) ->
+ do_transform(Forms).
+
+do_transform([{op, L, '!', Lhs, Rhs}|Fs]) ->
+ [NewLhs] = do_transform([Lhs]),
+ [NewRhs] = do_transform([Rhs]),
+ [{call, L, {remote, L, {atom, L, gproc}, {atom, L, send}},
+ [NewLhs, NewRhs]} | do_transform(Fs)];
+do_transform([]) ->
+ [];
+do_transform([F|Fs]) when is_tuple(F) ->
+ [list_to_tuple(do_transform(tuple_to_list(F))) | do_transform(Fs)];
+do_transform([F|Fs]) ->
+ [do_transform(F) | do_transform(Fs)];
+do_transform(F) ->
+ F.
View
24 test/gproc_pt_tests.erl
@@ -0,0 +1,24 @@
+-module(gproc_pt_tests).
+
+-include_lib("eunit/include/eunit.hrl").
+
+-compile({parse_transform, gproc_pt}).
+
+reg_and_send_test_() ->
+ {setup,
+ fun() -> application:start(gproc) end,
+ fun(_) -> application:stop(gproc) end,
+ [{"gproc", fun gproc/0}]
+ }.
+
+gproc() ->
+ gproc:reg({n, l, <<"test">>}),
+
+ Msg = random:uniform(1000),
+ {n, l, <<"test">>} ! Msg,
+
+ Echo = receive
+ V -> V
+ end,
+
+ ?assertEqual(Echo, Msg).
Please sign in to comment.
Something went wrong with that request. Please try again.