aboutsummaryrefslogtreecommitdiffstats
path: root/erts/doc/src/match_spec.xml
diff options
context:
space:
mode:
Diffstat (limited to 'erts/doc/src/match_spec.xml')
-rw-r--r--erts/doc/src/match_spec.xml1057
1 files changed, 653 insertions, 404 deletions
diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml
index 08dad8cc10..1b297c5d29 100644
--- a/erts/doc/src/match_spec.xml
+++ b/erts/doc/src/match_spec.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2013</year>
+ <year>1999</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -22,7 +22,7 @@
</legalnotice>
- <title>Match specifications in Erlang</title>
+ <title>Match Specifications in Erlang</title>
<prepared>Patrik Nyblom</prepared>
<responsible></responsible>
<docno></docno>
@@ -32,49 +32,54 @@
<rev>PA1</rev>
<file>match_spec.xml</file>
</header>
- <p>A "match specification" (match_spec) is an Erlang term describing a
- small "program" that will try to match something (either the
- parameters to a function as used in the <c><![CDATA[erlang:trace_pattern/2]]></c>
- BIF, or the objects in an ETS table.).
- The match_spec in many ways works like a small function in Erlang, but is
- interpreted/compiled by the Erlang runtime system to something much more
- efficient than calling an Erlang function. The match_spec is also
+ <p>A "match specification" (<c>match_spec</c>) is an Erlang term describing a
+ small "program" that tries to match something. It can be used
+ to either control tracing with
+ <seealso marker="erlang#trace_pattern/3">erlang:trace_pattern/3</seealso>
+ or to search for objects in an ETS table with for example
+ <seealso marker="stdlib:ets#select/2">ets:select/2</seealso>.
+ The match specification in many ways works like a small function in Erlang,
+ but is interpreted/compiled by the Erlang runtime system to something much more
+ efficient than calling an Erlang function. The match specification is also
very limited compared to the expressiveness of real Erlang functions.</p>
- <p>Match specifications are given to the BIF <c><![CDATA[erlang:trace_pattern/2]]></c> to
- execute matching of function arguments as well as to define some actions
- to be taken when the match succeeds (the <c><![CDATA[MatchBody]]></c> part). Match
- specifications can also be used in ETS, to specify objects to be
- returned from an <c><![CDATA[ets:select/2]]></c> call (or other select
- calls). The semantics and restrictions differ slightly when using
- match specifications for tracing and in ETS, the differences are
- defined in a separate paragraph below.</p>
- <p>The most notable difference between a match_spec and an Erlang fun is
- of course the syntax. Match specifications are Erlang terms, not
- Erlang code. A match_spec also has a somewhat strange concept of
- exceptions. An exception (e.g., <c><![CDATA[badarg]]></c>) in the <c><![CDATA[MatchCondition]]></c>
- part,
- which resembles an Erlang guard, will generate immediate failure,
- while an exception in the <c><![CDATA[MatchBody]]></c> part, which resembles the body of an
- Erlang function, is implicitly caught and results in the single atom
- <c><![CDATA['EXIT']]></c>.
- </p>
+ <p>The most notable difference between a match specification and an Erlang
+ fun is the syntax. Match specifications are Erlang terms, not Erlang code.
+ Also, a match specification has a strange concept of exceptions:</p>
+
+ <list type="bulleted">
+ <item>
+ <p>An exception (such as <c><![CDATA[badarg]]></c>) in the
+ <c><![CDATA[MatchCondition]]></c> part, which resembles an Erlang guard,
+ generates immediate failure.</p>
+ </item>
+ <item>
+ <p>An exception in the <c><![CDATA[MatchBody]]></c> part, which resembles
+ the body of an Erlang function, is implicitly caught and results in the
+ single atom <c><![CDATA['EXIT']]></c>.</p>
+ </item>
+ </list>
<section>
<title>Grammar</title>
- <p>A match_spec used in tracing can be described in this <em>informal</em> grammar:</p>
+ <p>A match specification used in tracing can be described in the following
+ <em>informal</em> grammar:</p>
+
<list type="bulleted">
<item>MatchExpression ::= [ MatchFunction, ... ]
</item>
<item>MatchFunction ::= { MatchHead, MatchConditions, MatchBody }
</item>
- <item>MatchHead ::= MatchVariable | <c><![CDATA['_']]></c> | [ MatchHeadPart, ... ]
+ <item>MatchHead ::= MatchVariable | <c><![CDATA['_']]></c> |
+ [ MatchHeadPart, ... ]
+ </item>
+ <item>MatchHeadPart ::= term() | MatchVariable | <c><![CDATA['_']]></c>
</item>
- <item>MatchHeadPart ::= term() | MatchVariable | <c><![CDATA['_']]></c></item>
<item>MatchVariable ::= '$&lt;number&gt;'
</item>
- <item>MatchConditions ::= [ MatchCondition, ...] | <c><![CDATA[[]]]></c></item>
- <item>MatchCondition ::= { GuardFunction } |
- { GuardFunction, ConditionExpression, ... }
+ <item>MatchConditions ::= [ MatchCondition, ...] | <c><![CDATA[[]]]></c>
+ </item>
+ <item>MatchCondition ::= { GuardFunction } | { GuardFunction,
+ ConditionExpression, ... }
</item>
<item>BoolFunction ::= <c><![CDATA[is_atom]]></c> |
<c><![CDATA[is_float]]></c> | <c><![CDATA[is_integer]]></c> |
@@ -85,58 +90,77 @@
<c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> |
<c><![CDATA[is_seq_trace]]></c> | <c><![CDATA['and']]></c> |
<c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> |
- <c><![CDATA['xor']]></c> | <c><![CDATA[andalso]]></c> |
- <c><![CDATA[orelse]]></c></item>
+ <c><![CDATA['xor']]></c> | <c><![CDATA['andalso']]></c> |
+ <c><![CDATA['orelse']]></c>
+ </item>
<item>ConditionExpression ::= ExprMatchVariable | { GuardFunction } |
- { GuardFunction, ConditionExpression, ... } | TermConstruct
+ { GuardFunction, ConditionExpression, ... } | TermConstruct
+ </item>
+ <item>ExprMatchVariable ::= MatchVariable (bound in the MatchHead) |
+ <c><![CDATA['$_']]></c> | <c><![CDATA['$$']]></c>
</item>
- <item>ExprMatchVariable ::= MatchVariable (bound in the MatchHead) |
- <c><![CDATA['$_']]></c> | <c><![CDATA['$$']]></c></item>
<item>TermConstruct = {{}} | {{ ConditionExpression, ... }} |
<c><![CDATA[[]]]></c> | [ConditionExpression, ...] |
<c><![CDATA[#{}]]></c> | #{term() => ConditionExpression, ...} |
- NonCompositeTerm | Constant</item>
- <item>NonCompositeTerm ::= term() (not list or tuple or map)</item>
+ NonCompositeTerm | Constant
+ </item>
+ <item>NonCompositeTerm ::= term() (not list or tuple or map)
+ </item>
<item>Constant ::= {<c><![CDATA[const]]></c>, term()}
</item>
<item>GuardFunction ::= BoolFunction | <c><![CDATA[abs]]></c> |
- <c><![CDATA[element]]></c> | <c><![CDATA[hd]]></c> | <c><![CDATA[length]]></c> | <c><![CDATA[node]]></c> |
- <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> | <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> |
- <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> | <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> |
- <c><![CDATA['rem']]></c> | <c><![CDATA['band']]></c> | <c><![CDATA['bor']]></c> | <c><![CDATA['bxor']]></c> |
- <c><![CDATA['bnot']]></c> | <c><![CDATA['bsl']]></c> | <c><![CDATA['bsr']]></c> | <c><![CDATA['>']]></c> |
- <c><![CDATA['>=']]></c> | <c><![CDATA['<']]></c> | <c><![CDATA['=<']]></c> | <c><![CDATA['=:=']]></c> |
- <c><![CDATA['==']]></c> | <c><![CDATA['=/=']]></c> | <c><![CDATA['/=']]></c> | <c><![CDATA[self]]></c> |
- <c><![CDATA[get_tcw]]></c></item>
+ <c><![CDATA[element]]></c> | <c><![CDATA[hd]]></c> |
+ <c><![CDATA[length]]></c> | <c><![CDATA[node]]></c> |
+ <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> |
+ <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> |
+ <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> |
+ <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> |
+ <c><![CDATA['rem']]></c> | <c><![CDATA['band']]></c> |
+ <c><![CDATA['bor']]></c> | <c><![CDATA['bxor']]></c> |
+ <c><![CDATA['bnot']]></c> | <c><![CDATA['bsl']]></c> |
+ <c><![CDATA['bsr']]></c> | <c><![CDATA['>']]></c> |
+ <c><![CDATA['>=']]></c> | <c><![CDATA['<']]></c> |
+ <c><![CDATA['=<']]></c> | <c><![CDATA['=:=']]></c> |
+ <c><![CDATA['==']]></c> | <c><![CDATA['=/=']]></c> |
+ <c><![CDATA['/=']]></c> | <c><![CDATA[self]]></c> |
+ <c><![CDATA[get_tcw]]></c>
+ </item>
<item>MatchBody ::= [ ActionTerm ]
</item>
<item>ActionTerm ::= ConditionExpression | ActionCall
</item>
- <item>ActionCall ::= {ActionFunction} |
- {ActionFunction, ActionTerm, ...}
+ <item>ActionCall ::= {ActionFunction} | {ActionFunction, ActionTerm, ...}
</item>
<item>ActionFunction ::= <c><![CDATA[set_seq_token]]></c> |
- <c><![CDATA[get_seq_token]]></c> | <c><![CDATA[message]]></c> |
- <c><![CDATA[return_trace]]></c> | <c><![CDATA[exception_trace]]></c> | <c><![CDATA[process_dump]]></c> |
- <c><![CDATA[enable_trace]]></c> | <c><![CDATA[disable_trace]]></c> | <c><![CDATA[trace]]></c> |
- <c><![CDATA[display]]></c> | <c><![CDATA[caller]]></c> | <c><![CDATA[set_tcw]]></c> |
- <c><![CDATA[silent]]></c></item>
+ <c><![CDATA[get_seq_token]]></c> | <c><![CDATA[message]]></c> |
+ <c><![CDATA[return_trace]]></c> | <c><![CDATA[exception_trace]]></c> |
+ <c><![CDATA[process_dump]]></c> | <c><![CDATA[enable_trace]]></c> |
+ <c><![CDATA[disable_trace]]></c> | <c><![CDATA[trace]]></c> |
+ <c><![CDATA[display]]></c> | <c><![CDATA[caller]]></c> |
+ <c><![CDATA[set_tcw]]></c> | <c><![CDATA[silent]]></c>
+ </item>
</list>
- <p>A match_spec used in ets can be described in this <em>informal</em> grammar:</p>
+ <p>A match specification used in
+ <seealso marker="stdlib:ets"><c>stdlib:ets(3)</c></seealso>
+ can be described in the following <em>informal</em> grammar:</p>
+
<list type="bulleted">
<item>MatchExpression ::= [ MatchFunction, ... ]
</item>
<item>MatchFunction ::= { MatchHead, MatchConditions, MatchBody }
</item>
- <item>MatchHead ::= MatchVariable | <c><![CDATA['_']]></c> | { MatchHeadPart, ... }
+ <item>MatchHead ::= MatchVariable | <c><![CDATA['_']]></c> |
+ { MatchHeadPart, ... }
+ </item>
+ <item>MatchHeadPart ::= term() | MatchVariable | <c><![CDATA['_']]></c>
</item>
- <item>MatchHeadPart ::= term() | MatchVariable | <c><![CDATA['_']]></c></item>
<item>MatchVariable ::= '$&lt;number&gt;'
</item>
- <item>MatchConditions ::= [ MatchCondition, ...] | <c><![CDATA[[]]]></c></item>
+ <item>MatchConditions ::= [ MatchCondition, ...] | <c><![CDATA[[]]]></c>
+ </item>
<item>MatchCondition ::= { GuardFunction } |
- { GuardFunction, ConditionExpression, ... }
+ { GuardFunction, ConditionExpression, ... }
</item>
<item>BoolFunction ::= <c><![CDATA[is_atom]]></c> |
<c><![CDATA[is_float]]></c> | <c><![CDATA[is_integer]]></c> |
@@ -147,464 +171,688 @@
<c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> |
<c><![CDATA[is_seq_trace]]></c> | <c><![CDATA['and']]></c> |
<c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> |
- <c><![CDATA['xor']]></c> | <c><![CDATA[andalso]]></c> |
- <c><![CDATA[orelse]]></c></item>
+ <c><![CDATA['xor']]></c> | <c><![CDATA['andalso']]></c> |
+ <c><![CDATA['orelse']]></c>
+ </item>
<item>ConditionExpression ::= ExprMatchVariable | { GuardFunction } |
- { GuardFunction, ConditionExpression, ... } | TermConstruct
+ { GuardFunction, ConditionExpression, ... } | TermConstruct
</item>
<item>ExprMatchVariable ::= MatchVariable (bound in the MatchHead) |
- <c><![CDATA['$_']]></c> | <c><![CDATA['$$']]></c></item>
+ <c><![CDATA['$_']]></c> | <c><![CDATA['$$']]></c>
+ </item>
<item>TermConstruct = {{}} | {{ ConditionExpression, ... }} |
<c><![CDATA[[]]]></c> | [ConditionExpression, ...] | #{} |
- #{term() => ConditionExpression, ...} | NonCompositeTerm |
- Constant</item>
- <item>NonCompositeTerm ::= term() (not list or tuple or map)</item>
+ #{term() => ConditionExpression, ...} | NonCompositeTerm | Constant
+ </item>
+ <item>NonCompositeTerm ::= term() (not list or tuple or map)
+ </item>
<item>Constant ::= {<c><![CDATA[const]]></c>, term()}
</item>
<item>GuardFunction ::= BoolFunction | <c><![CDATA[abs]]></c> |
- <c><![CDATA[element]]></c> | <c><![CDATA[hd]]></c> | <c><![CDATA[length]]></c> | <c><![CDATA[node]]></c> |
- <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> | <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> |
- <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> | <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> |
- <c><![CDATA['rem']]></c> | <c><![CDATA['band']]></c> | <c><![CDATA['bor']]></c> | <c><![CDATA['bxor']]></c> |
- <c><![CDATA['bnot']]></c> | <c><![CDATA['bsl']]></c> | <c><![CDATA['bsr']]></c> | <c><![CDATA['>']]></c> |
- <c><![CDATA['>=']]></c> | <c><![CDATA['<']]></c> | <c><![CDATA['=<']]></c> | <c><![CDATA['=:=']]></c> |
- <c><![CDATA['==']]></c> | <c><![CDATA['=/=']]></c> | <c><![CDATA['/=']]></c> | <c><![CDATA[self]]></c> |
- <c><![CDATA[get_tcw]]></c></item>
- <item>MatchBody ::= [ ConditionExpression, ... ]</item>
+ <c><![CDATA[element]]></c> | <c><![CDATA[hd]]></c> |
+ <c><![CDATA[length]]></c> | <c><![CDATA[node]]></c> |
+ <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> |
+ <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> |
+ <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> |
+ <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> |
+ <c><![CDATA['rem']]></c> | <c><![CDATA['band']]></c> |
+ <c><![CDATA['bor']]></c> | <c><![CDATA['bxor']]></c> |
+ <c><![CDATA['bnot']]></c> | <c><![CDATA['bsl']]></c> |
+ <c><![CDATA['bsr']]></c> | <c><![CDATA['>']]></c> |
+ <c><![CDATA['>=']]></c> | <c><![CDATA['<']]></c> |
+ <c><![CDATA['=<']]></c> | <c><![CDATA['=:=']]></c> |
+ <c><![CDATA['==']]></c> | <c><![CDATA['=/=']]></c> |
+ <c><![CDATA['/=']]></c> | <c><![CDATA[self]]></c> |
+ <c><![CDATA[get_tcw]]></c>
+ </item>
+ <item>MatchBody ::= [ ConditionExpression, ... ]
+ </item>
</list>
</section>
<section>
- <title>Function descriptions</title>
-
+ <title>Function Descriptions</title>
<section>
- <title>Functions allowed in all types of match specifications</title>
- <p>The different functions allowed in <c><![CDATA[match_spec]]></c> work like this:
- </p>
- <p><em>is_atom, is_float, is_integer, is_list, is_number, is_pid, is_port,
- is_reference, is_tuple, is_map, is_binary, is_function:</em> Like the
- corresponding guard tests in Erlang, return <c><![CDATA[true]]></c> or
- <c><![CDATA[false]]></c>.</p>
- <p><em>is_record: </em>Takes an additional parameter, which SHALL
- be the result of <c><![CDATA[record_info(size, <record_type>)]]></c>,
- like in <c><![CDATA[{is_record, '$1', rectype, record_info(size, rectype)}]]></c>.
- </p>
- <p><em>'not': </em>Negates its single argument (anything other
- than <c><![CDATA[false]]></c> gives <c><![CDATA[false]]></c>).
- </p>
- <p><em>'and': </em>Returns <c><![CDATA[true]]></c> if all its arguments
- (variable length argument list) evaluate to <c><![CDATA[true]]></c>, else
- <c><![CDATA[false]]></c>. Evaluation order is undefined.
- </p>
- <p><em>'or': </em>Returns <c><![CDATA[true]]></c> if any of its arguments
- evaluates to <c><![CDATA[true]]></c>. Variable length argument
- list. Evaluation order is undefined.
- </p>
- <p><em>andalso: </em>Like <c><![CDATA['and']]></c>, but quits evaluating its
- arguments as soon as one argument evaluates to something else
- than true. Arguments are evaluated left to right.
- </p>
- <p><em>orelse: </em>Like <c><![CDATA['or']]></c>, but quits evaluating as soon
- as one of its arguments evaluates to <c><![CDATA[true]]></c>. Arguments are
- evaluated left to right.
- </p>
- <p><em>'xor': </em>Only two arguments, of which one has to be true
- and the other false to return <c><![CDATA[true]]></c>; otherwise
- <c><![CDATA['xor']]></c> returns false.
- </p>
- <p><em>abs, element, hd, length, node, round, size, tl, trunc, '+', '-', '*', 'div', 'rem', 'band', 'bor', 'bxor', 'bnot', 'bsl', 'bsr', '>', '>=', '&lt;', '=&lt;', '=:=', '==', '=/=', '/=', self: </em>Work as the corresponding Erlang bif's (or
- operators). In case of bad arguments, the result depends on
- the context. In the <c><![CDATA[MatchConditions]]></c> part of the
- expression, the test fails immediately (like in an Erlang
- guard), but in the <c><![CDATA[MatchBody]]></c>, exceptions are implicitly
- caught and the call results in the atom <c><![CDATA['EXIT']]></c>.</p>
+ <title>Functions Allowed in All Types of Match Specifications</title>
+ <p>The functions allowed in <c><![CDATA[match_spec]]></c> work as
+ follows:</p>
+
+ <taglist>
+ <tag><c>is_atom</c>, <c>is_float</c>, <c>is_integer</c>, <c>is_list</c>,
+ <c>is_number</c>, <c>is_pid</c>, <c>is_port</c>, <c>is_reference</c>,
+ <c>is_tuple</c>, <c>is_map</c>, <c>is_binary</c>, <c>is_function</c>
+ </tag>
+ <item>
+ <p>Same as the corresponding guard tests in Erlang, return
+ <c><![CDATA[true]]></c> or <c><![CDATA[false]]></c>.</p>
+ </item>
+ <tag><c>is_record</c></tag>
+ <item>
+ <p>Takes an additional parameter, which <em>must</em> be the result
+ of <c><![CDATA[record_info(size, <record_type>)]]></c>, like in
+ <c><![CDATA[{is_record, '$1', rectype, record_info(size,
+ rectype)}]]></c>.</p>
+ </item>
+ <tag><c>'not'</c></tag>
+ <item>
+ <p>Negates its single argument (anything other
+ than <c><![CDATA[false]]></c> gives <c><![CDATA[false]]></c>).</p>
+ </item>
+ <tag><c>'and'</c></tag>
+ <item>
+ <p>Returns <c><![CDATA[true]]></c> if all its arguments (variable
+ length argument list) evaluate to <c><![CDATA[true]]></c>, otherwise
+ <c><![CDATA[false]]></c>. Evaluation order is undefined.</p>
+ </item>
+ <tag><c>'or'</c></tag>
+ <item>
+ <p>Returns <c><![CDATA[true]]></c> if any of its arguments
+ evaluates to <c><![CDATA[true]]></c>. Variable length argument
+ list. Evaluation order is undefined.</p>
+ </item>
+ <tag><c>'andalso'</c></tag>
+ <item>
+ <p>Works as <c><![CDATA['and']]></c>, but quits evaluating its
+ arguments when one argument evaluates to something else
+ than <c>true</c>. Arguments are evaluated left to right.</p>
+ </item>
+ <tag><c>'orelse'</c></tag>
+ <item>
+ <p>Works as <c><![CDATA['or']]></c>, but quits evaluating as soon
+ as one of its arguments evaluates to <c><![CDATA[true]]></c>.
+ Arguments are evaluated left to right.</p>
+ </item>
+ <tag><c>'xor'</c></tag>
+ <item>
+ <p>Only two arguments, of which one must be <c>true</c> and the
+ other <c>false</c> to return <c><![CDATA[true]]></c>; otherwise
+ <c><![CDATA['xor']]></c> returns false.</p>
+ </item>
+ <tag><c>abs</c>, <c>element</c>, <c>hd</c>, <c>length</c>, <c>node</c>,
+ <c>round</c>, <c>size</c>, <c>tl</c>, <c>trunc</c>, <c>'+'</c>,
+ <c>'-'</c>, <c>'*'</c>, <c>'div'</c>, <c>'rem'</c>, <c>'band'</c>,
+ <c>'bor'</c>, <c>'bxor'</c>, <c>'bnot'</c>, <c>'bsl'</c>,
+ <c>'bsr'</c>, <c>'>'</c>, <c>'>='</c>, <c>'&lt;'</c>, <c>'=&lt;'</c>,
+ <c>'=:='</c>, <c>'=='</c>, <c>'=/='</c>, <c>'/='</c>,
+ <c>self</c></tag>
+ <item>
+ <p>Same as the corresponding Erlang BIFs (or operators). In case of
+ bad arguments, the result depends on the context. In the
+ <c><![CDATA[MatchConditions]]></c> part of the expression, the test
+ fails immediately (like in an Erlang guard). In the
+ <c><![CDATA[MatchBody]]></c> part, exceptions are implicitly caught
+ and the call results in the atom <c><![CDATA['EXIT']]></c>.</p>
+ </item>
+ </taglist>
</section>
<section>
- <title>Functions allowed only for tracing</title>
- <p><em>is_seq_trace: </em>Returns <c><![CDATA[true]]></c> if a sequential
- trace token is set for the current process, otherwise <c><![CDATA[false]]></c>.
- </p>
- <p><em>set_seq_token:</em> Works like
- <c><![CDATA[seq_trace:set_token/2]]></c>, but returns <c><![CDATA[true]]></c> on success
- and <c><![CDATA['EXIT']]></c> on error or bad argument. Only allowed in the
- <c><![CDATA[MatchBody]]></c> part and only allowed when tracing.
- </p>
- <p><em>get_seq_token:</em> Works just like
- <c><![CDATA[seq_trace:get_token/0]]></c>, and is only allowed in the
- <c><![CDATA[MatchBody]]></c> part when tracing.
- </p>
- <p><em>message:</em> Sets an additional message appended to the
- trace message sent. One can only set one additional message in
- the body; subsequent calls will replace the appended message. As
- a special case, <c><![CDATA[{message, false}]]></c> disables sending of
- trace messages ('call' and 'return_to')
- for this function call, just like if the match_spec had not matched,
- which can be useful if only the side effects of
- the <c><![CDATA[MatchBody]]></c> are desired.
- Another special case is <c><![CDATA[{message, true}]]></c> which
- sets the default behavior, as if the function had no match_spec,
- trace message is sent with no extra
- information (if no other calls to <c><![CDATA[message]]></c> are placed
- before <c><![CDATA[{message, true}]]></c>, it is in fact a "noop").
- </p>
- <p>Takes one argument, the message. Returns <c><![CDATA[true]]></c> and can
- only be used in the <c><![CDATA[MatchBody]]></c> part and when tracing.
- </p>
- <p><em>return_trace:</em> Causes a <c><![CDATA[return_from]]></c> trace
- message to be sent upon return from the current function.
- Takes no arguments, returns <c><![CDATA[true]]></c> and can only be used
- in the <c><![CDATA[MatchBody]]></c> part when tracing.
- If the process trace flag <c><![CDATA[silent]]></c>
- is active the <c><![CDATA[return_from]]></c> trace message is inhibited.
- </p>
- <p>NOTE! If the traced function is tail recursive, this match
- spec function destroys that property.
- Hence, if a match spec executing this function is used on a
- perpetual server process, it may only be active for a limited
- time, or the emulator will eventually use all memory in the host
- machine and crash. If this match_spec function is inhibited
- using the <c><![CDATA[silent]]></c> process trace flag
- tail recursiveness still remains.
- </p>
- <p><em>exception_trace:</em> Same as <em>return_trace</em>,
- plus; if the traced function exits due to an exception,
- an <c><![CDATA[exception_from]]></c> trace message is generated,
- whether the exception is caught or not.
- </p>
- <p><em>process_dump:</em> Returns some textual information about
- the current process as a binary. Takes no arguments and is only
- allowed in the <c><![CDATA[MatchBody]]></c> part when tracing.
- </p>
- <p><em>enable_trace:</em> With one parameter this function turns
- on tracing like the Erlang call <c><![CDATA[erlang:trace(self(), true, [P2])]]></c>, where <c><![CDATA[P2]]></c> is the parameter to
- <c><![CDATA[enable_trace]]></c>. With two parameters, the first parameter
- should be either a process identifier or the registered name of
- a process. In this case tracing is turned on for the designated
- process in the same way as in the Erlang call <c><![CDATA[erlang:trace(P1, true, [P2])]]></c>, where P1 is the first and P2 is the second
- argument. The process <c><![CDATA[P1]]></c> gets its trace messages sent to the same
- tracer as the process executing the statement uses. <c><![CDATA[P1]]></c>
- can <em>not</em> be one of the atoms <c><![CDATA[all]]></c>, <c><![CDATA[new]]></c> or
- <c><![CDATA[existing]]></c> (unless, of course, they are registered names).
- <c><![CDATA[P2]]></c> can <em>not</em> be <c><![CDATA[cpu_timestamp]]></c> nor
- <c><![CDATA[{tracer,_}]]></c>.
- Returns <c><![CDATA[true]]></c> and may only be used in
- the <c><![CDATA[MatchBody]]></c> part when tracing.
- </p>
- <p><em>disable_trace:</em> With one parameter this function
- disables tracing like the Erlang call <c><![CDATA[erlang:trace(self(), false, [P2])]]></c>, where <c><![CDATA[P2]]></c> is the parameter to
- <c><![CDATA[disable_trace]]></c>. With two parameters it works like the
- Erlang call <c><![CDATA[erlang:trace(P1, false, [P2])]]></c>, where P1 can
- be either a process identifier or a registered name and is given
- as the first argument to the match_spec function.
- <c><![CDATA[P2]]></c> can <em>not</em> be <c><![CDATA[cpu_timestamp]]></c> nor
- <c><![CDATA[{tracer,_}]]></c>. Returns
- <c><![CDATA[true]]></c> and may only be used in the <c><![CDATA[MatchBody]]></c> part
- when tracing.
- </p>
- <p><em>trace:</em> With two parameters this function takes a list
- of trace flags to disable as first parameter and a list
- of trace flags to enable as second parameter. Logically, the
- disable list is applied first, but effectively all changes
- are applied atomically. The trace flags
- are the same as for <c><![CDATA[erlang:trace/3]]></c> not including
- <c><![CDATA[cpu_timestamp]]></c> but including <c><![CDATA[{tracer,_}]]></c>. If a
- tracer is specified in both lists, the tracer in the
- enable list takes precedence. If no tracer is specified the
- same tracer as the process executing the match spec is
- used. With three parameters to this function the first is
- either a process identifier or the registered name of a
- process to set trace flags on, the second is the disable
- list, and the third is the enable list. Returns
- <c><![CDATA[true]]></c> if any trace property was changed for the
- trace target process or <c><![CDATA[false]]></c> if not. It may only
- be used in the <c><![CDATA[MatchBody]]></c> part when tracing.
- </p>
- <p><em>caller:</em>
- Returns the calling function as a tuple {Module,
- Function, Arity} or the atom <c><![CDATA[undefined]]></c> if the calling
- function cannot be determined. May only be used in the
- <c><![CDATA[MatchBody]]></c> part when tracing.
- </p>
- <p>Note that if a "technically built in function" (i.e. a
- function not written in Erlang) is traced, the <c><![CDATA[caller]]></c>
- function will sometimes return the atom <c><![CDATA[undefined]]></c>. The calling
- Erlang function is not available during such calls.
- </p>
- <p><em>display:</em> For debugging purposes only; displays the
- single argument as an Erlang term on stdout, which is seldom
- what is wanted. Returns <c><![CDATA[true]]></c> and may only be used in the
- <c><![CDATA[MatchBody]]></c> part when tracing.
- </p>
- <p> <marker id="get_tcw"></marker>
-<em>get_tcw:</em>
- Takes no argument and returns the value of the node's trace
- control word. The same is done by
- <c><![CDATA[erlang:system_info(trace_control_word)]]></c>.
- </p>
- <p>The trace control word is a 32-bit unsigned integer intended for
- generic trace control. The trace control word can be tested and
- set both from within trace match specifications and with BIFs.
- This call is only allowed when tracing.
- </p>
- <p> <marker id="set_tcw"></marker>
-<em>set_tcw:</em>
- Takes one unsigned integer argument, sets the value of
- the node's trace control word to the value of the argument
- and returns the previous value. The same is done by
- <c><![CDATA[erlang:system_flag(trace_control_word, Value)]]></c>. It is only
- allowed to use <c><![CDATA[set_tcw]]></c> in the <c><![CDATA[MatchBody]]></c> part
- when tracing.
- </p>
- <p><em>silent:</em>
- Takes one argument. If the argument is <c><![CDATA[true]]></c>, the call
- trace message mode for the current process is set to silent
- for this call and all subsequent, i.e call trace messages
- are inhibited even if <c><![CDATA[{message, true}]]></c> is called in the
- <c><![CDATA[MatchBody]]></c> part for a traced function.
- </p>
- <p>This mode can also be activated with the <c><![CDATA[silent]]></c> flag
- to <c><![CDATA[erlang:trace/3]]></c>.
- </p>
- <p>If the argument is <c><![CDATA[false]]></c>, the call trace message mode
- for the current process is set to normal (non-silent) for
- this call and all subsequent.
- </p>
- <p>If the argument is neither <c><![CDATA[true]]></c> nor <c><![CDATA[false]]></c>,
- the call trace message mode is unaffected.</p>
+ <title>Functions Allowed Only for Tracing</title>
+ <p>The functions allowed only for tracing work as follows:</p>
+
+ <taglist>
+ <tag><c>is_seq_trace</c></tag>
+ <item>
+ <p>Returns <c><![CDATA[true]]></c> if a sequential trace token is set
+ for the current process, otherwise <c><![CDATA[false]]></c>.</p>
+ </item>
+ <tag><c>set_seq_token</c></tag>
+ <item>
+ <p>Works as <c><![CDATA[seq_trace:set_token/2]]></c>, but returns
+ <c><![CDATA[true]]></c> on success, and <c><![CDATA['EXIT']]></c>
+ on error or bad argument. Only allowed in the
+ <c><![CDATA[MatchBody]]></c> part and only allowed when tracing.</p>
+ </item>
+ <tag><c>get_seq_token</c></tag>
+ <item>
+ <p>Same as <c><![CDATA[seq_trace:get_token/0]]></c> and only
+ allowed in the <c><![CDATA[MatchBody]]></c> part when tracing.</p>
+ </item>
+ <tag><c>message</c></tag>
+ <item>
+ <p>Sets an additional message appended to the
+ trace message sent. One can only set one additional message in
+ the body. Later calls replace the appended message.</p>
+ <p>As a special case, <c><![CDATA[{message, false}]]></c> disables
+ sending of trace messages ('call' and 'return_to') for this function
+ call, just like if the match specification had not matched.
+ This can be useful if only the side effects of
+ the <c><![CDATA[MatchBody]]></c> part are desired.</p>
+ <p>Another special case is <c><![CDATA[{message, true}]]></c>, which
+ sets the default behavior, as if the function had no match
+ specification; trace message is sent with no extra information
+ (if no other calls to <c><![CDATA[message]]></c> are placed before
+ <c><![CDATA[{message, true}]]></c>, it is in fact a "noop").</p>
+ <p>Takes one argument: the message. Returns <c><![CDATA[true]]></c>
+ and can only be used in the <c><![CDATA[MatchBody]]></c> part and
+ when tracing.</p>
+ </item>
+ <tag><c>return_trace</c></tag>
+ <item>
+ <p>Causes a <c><![CDATA[return_from]]></c> trace message to be sent
+ upon return from the current function. Takes no arguments, returns
+ <c><![CDATA[true]]></c> and can only be used in the
+ <c><![CDATA[MatchBody]]></c> part when tracing.
+ If the process trace flag <c><![CDATA[silent]]></c> is active, the
+ <c><![CDATA[return_from]]></c> trace message is inhibited.</p>
+ <p><em>Warning:</em> If the traced function is tail-recursive, this
+ match specification function destroys that property. Hence, if a
+ match specification executing this function is used on a
+ perpetual server process, it can only be active for a limited
+ period of time, or the emulator will eventually use all memory in
+ the host machine and crash. If this match specification function is
+ inhibited using process trace flag <c><![CDATA[silent]]></c>,
+ tail-recursiveness still remains.</p>
+ </item>
+ <tag><c>exception_trace</c></tag>
+ <item>
+ <p>Works as <c>return_trace</c> plus; if the traced function exits
+ because of an exception,
+ an <c><![CDATA[exception_from]]></c> trace message is generated,
+ regardless of the exception is caught or not.</p>
+ </item>
+ <tag><c>process_dump</c></tag>
+ <item>
+ <p>Returns some textual information about
+ the current process as a binary. Takes no arguments and is only
+ allowed in the <c><![CDATA[MatchBody]]></c> part when tracing.</p>
+ </item>
+ <tag><c>enable_trace</c></tag>
+ <item>
+ <p>With one parameter this function turns on tracing like the Erlang
+ call <c><![CDATA[erlang:trace(self(), true, [P2])]]></c>, where
+ <c><![CDATA[P2]]></c> is the parameter to
+ <c><![CDATA[enable_trace]]></c>.</p>
+ <p>With two parameters, the first parameter is to be either a process
+ identifier or the registered name of a process. In this case tracing
+ is turned on for the designated process in the same way as in the
+ Erlang call <c><![CDATA[erlang:trace(P1, true, [P2])]]></c>, where
+ <c>P1</c> is the first and <c>P2</c> is the second argument. The
+ process <c><![CDATA[P1]]></c> gets its trace messages sent to the
+ same tracer as the process executing the statement uses.
+ <c><![CDATA[P1]]></c> <em>cannot</em> be one of the atoms
+ <c><![CDATA[all]]></c>, <c><![CDATA[new]]></c> or
+ <c><![CDATA[existing]]></c> (unless they are registered names).
+ <c><![CDATA[P2]]></c> <em>cannot</em> be
+ <c><![CDATA[cpu_timestamp]]></c> or <c><![CDATA[tracer]]></c>.</p>
+ <p>Returns <c><![CDATA[true]]></c> and can only be used in
+ the <c><![CDATA[MatchBody]]></c> part when tracing.</p>
+ </item>
+ <tag><c>disable_trace</c></tag>
+ <item>
+ <p>With one parameter this function disables tracing like the Erlang
+ call <c><![CDATA[erlang:trace(self(), false, [P2])]]></c>, where
+ <c><![CDATA[P2]]></c> is the parameter to
+ <c><![CDATA[disable_trace]]></c>.</p>
+ <p>With two parameters this function works as the Erlang call
+ <c><![CDATA[erlang:trace(P1, false, [P2])]]></c>, where <c>P1</c>
+ can be either a process identifier or a registered name and is
+ specified as the first argument to the match specification function.
+ <c><![CDATA[P2]]></c> <em>cannot</em> be
+ <c><![CDATA[cpu_timestamp]]></c> or <c><![CDATA[tracer]]></c>.</p>
+ <p>Returns <c><![CDATA[true]]></c> and can only be used in the
+ <c><![CDATA[MatchBody]]></c> part when tracing.</p>
+ </item>
+ <tag><c>trace</c></tag>
+ <item>
+ <p>With two parameters this function takes a list
+ of trace flags to disable as first parameter and a list
+ of trace flags to enable as second parameter. Logically, the
+ disable list is applied first, but effectively all changes
+ are applied atomically. The trace flags
+ are the same as for <c><![CDATA[erlang:trace/3]]></c>,
+ not including <c><![CDATA[cpu_timestamp]]></c>, but including
+ <c><![CDATA[tracer]]></c>.</p>
+ <p>If a tracer is specified in both lists, the tracer in the
+ enable list takes precedence. If no tracer is specified, the same
+ tracer as the process executing the match specification is used.</p>
+ <p>When using a <seealso marker="erl_tracer">tracer module</seealso>,
+ the module must be loaded before the match specification is
+ executed. If it is not loaded, the match fails.</p>
+ <p>With three parameters to this function, the first is
+ either a process identifier or the registered name of a
+ process to set trace flags on, the second is the disable
+ list, and the third is the enable list.</p>
+ <p>Returns <c><![CDATA[true]]></c> if any trace property was changed
+ for the trace target process, otherwise <c><![CDATA[false]]></c>.
+ Can only be used in the <c><![CDATA[MatchBody]]></c> part when
+ tracing.</p>
+ </item>
+ <tag><c>caller</c></tag>
+ <item>
+ <p>Returns the calling function as a tuple <c>{Module, Function,
+ Arity}</c> or the atom <c><![CDATA[undefined]]></c> if the calling
+ function cannot be determined. Can only be used in the
+ <c><![CDATA[MatchBody]]></c> part when tracing.</p>
+ <p>Notice that if a "technically built in function" (that is, a
+ function not written in Erlang) is traced, the
+ <c><![CDATA[caller]]></c> function sometimes returns the atom
+ <c><![CDATA[undefined]]></c>. The calling
+ Erlang function is not available during such calls.</p>
+ </item>
+ <tag><c>display</c></tag>
+ <item>
+ <p>For debugging purposes only. Displays the single argument as an
+ Erlang term on <c>stdout</c>, which is seldom what is wanted.
+ Returns <c><![CDATA[true]]></c> and can only be used in the
+ <c><![CDATA[MatchBody]]></c> part when tracing.</p>
+ </item>
+ <tag><marker id="get_tcw"/><c>get_tcw</c></tag>
+ <item>
+ <p>Takes no argument and returns the value of the node's trace
+ control word. The same is done by
+ <c><![CDATA[erlang:system_info(trace_control_word)]]></c>.</p>
+ <p>The trace control word is a 32-bit unsigned integer intended for
+ generic trace control. The trace control word can be tested and
+ set both from within trace match specifications and with BIFs.
+ This call is only allowed when tracing.</p>
+ </item>
+ <tag><marker id="set_tcw"/><c>set_tcw</c></tag>
+ <item>
+ <p>Takes one unsigned integer argument, sets the value of
+ the node's trace control word to the value of the argument,
+ and returns the previous value. The same is done by
+ <c><![CDATA[erlang:system_flag(trace_control_word, Value)]]></c>.
+ It is only allowed to use <c><![CDATA[set_tcw]]></c> in the
+ <c><![CDATA[MatchBody]]></c> part when tracing.</p>
+ </item>
+ <tag><c>silent</c></tag>
+ <item>
+ <p>Takes one argument. If the argument is <c><![CDATA[true]]></c>,
+ the call trace message mode for the current process is set to
+ silent for this call and all later calls, that is, call trace
+ messages are inhibited even if
+ <c><![CDATA[{message, true}]]></c> is called in the
+ <c><![CDATA[MatchBody]]></c> part for a traced function.</p>
+ <p>This mode can also be activated with flag
+ <c><![CDATA[silent]]></c> to
+ <c><![CDATA[erlang:trace/3]]></c>.</p>
+ <p>If the argument is <c><![CDATA[false]]></c>, the call trace
+ message mode for the current process is set to normal
+ (non-silent) for this call and all later calls.</p>
+ <p>If the argument is not <c><![CDATA[true]]></c> or
+ <c><![CDATA[false]]></c>, the call trace message mode is
+ unaffected.</p>
+ </item>
+ </taglist>
</section>
- <p><em>Note</em> that all "function calls" have to be tuples,
- even if they take no arguments. The value of <c><![CDATA[self]]></c> is
- the atom() <c><![CDATA[self]]></c>, but the value of <c><![CDATA[{self}]]></c> is
- the pid() of the current process.</p>
+
+ <note>
+ <p>All "function calls" must be tuples, even if they take no arguments.
+ The value of <c><![CDATA[self]]></c> is the atom()
+ <c><![CDATA[self]]></c>, but the value of <c><![CDATA[{self}]]></c> is
+ the pid() of the current process.</p>
+ </note>
</section>
<section>
- <title>Variables and literals</title>
- <p>Variables take the form <c><![CDATA['$<number>']]></c> where
- <c><![CDATA[<number>]]></c> is an integer between 0 (zero) and
- 100000000 (1e+8), the behavior if the number is outside these
- limits is <em>undefined</em>. In the <c><![CDATA[MatchHead]]></c> part, the special
- variable <c><![CDATA['_']]></c> matches anything, and never gets bound (like
- <c><![CDATA[_]]></c> in Erlang). In the <c><![CDATA[MatchCondition/MatchBody]]></c>
- parts, no unbound variables are allowed, why <c><![CDATA['_']]></c> is
- interpreted as itself (an atom). Variables can only be bound in
- the <c><![CDATA[MatchHead]]></c> part. In the <c><![CDATA[MatchBody]]></c> and
- <c><![CDATA[MatchCondition]]></c> parts, only variables bound previously may
- be used. As a special case, in the
- <c><![CDATA[MatchCondition/MatchBody]]></c> parts, the variable <c><![CDATA['$_']]></c>
- expands to the whole expression which matched the
- <c><![CDATA[MatchHead]]></c> (i.e., the whole parameter list to the possibly
- traced function or the whole matching object in the ets table)
- and the variable <c><![CDATA['$$']]></c> expands to a list
- of the values of all bound variables in order
- (i.e. <c><![CDATA[['$1','$2', ...]]]></c>).
- </p>
- <p>In the <c><![CDATA[MatchHead]]></c> part, all literals (except the variables
- noted above) are interpreted as is. In the
- <c><![CDATA[MatchCondition/MatchBody]]></c> parts, however, the
- interpretation is in some ways different. Literals in the
- <c><![CDATA[MatchCondition/MatchBody]]></c> can either be written as is,
- which works for all literals except tuples, or by using the
- special form <c><![CDATA[{const, T}]]></c>, where <c><![CDATA[T]]></c> is any Erlang
- term. For tuple literals in the match_spec, one can also use
- double tuple parentheses, i.e., construct them as a tuple of
+ <marker id="match_target"/>
+ <title>Match target</title>
+ <p>Each execution of a match specification is done against
+ a match target term. The format and content of the target term
+ depends on the context in which the match is done. The match
+ target for ETS is always a full table tuple. The match target
+ for call trace is always a list of all function arguments. The
+ match target for event trace depends on the event type, see
+ table below.</p>
+ <table>
+ <row>
+ <cell align="left" valign="middle">Context</cell>
+ <cell align="left" valign="middle">Type</cell>
+ <cell align="left" valign="middle">Match target</cell>
+ <cell align="left" valign="middle">Description</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">ETS</cell>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">{Key, Value1, Value2, ...}</cell>
+ <cell align="left" valign="middle">A table object</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Trace</cell>
+ <cell align="left" valign="middle">call</cell>
+ <cell align="left" valign="middle">[Arg1, Arg2, ...]</cell>
+ <cell align="left" valign="middle">Function arguments</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Trace</cell>
+ <cell align="left" valign="middle">send</cell>
+ <cell align="left" valign="middle">[Receiver, Message]</cell>
+ <cell align="left" valign="middle">Receiving process/port and message term</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Trace</cell>
+ <cell align="left" valign="middle">'receive'</cell>
+ <cell align="left" valign="middle">[Node, Sender, Message]</cell>
+ <cell align="left" valign="middle">Sending node, process/port and message term</cell>
+ </row>
+ <tcaption>Match target depending on context</tcaption>
+ </table>
+ </section>
+
+ <section>
+ <title>Variables and Literals</title>
+ <p>Variables take the form <c><![CDATA['$<number>']]></c>, where
+ <c><![CDATA[<number>]]></c> is an integer between 0 and
+ 100,000,000 (1e+8). The behavior if the number is outside these limits
+ is <em>undefined</em>. In the <c><![CDATA[MatchHead]]></c> part, the
+ special variable <c><![CDATA['_']]></c> matches anything, and never gets
+ bound (like <c><![CDATA[_]]></c> in Erlang).</p>
+
+ <list type="bulleted">
+ <item>
+ <p>In the <c><![CDATA[MatchCondition/MatchBody]]></c> parts,
+ no unbound variables are allowed, so <c><![CDATA['_']]></c> is
+ interpreted as itself (an atom). Variables can only be bound in the
+ <c><![CDATA[MatchHead]]></c> part.</p>
+ </item>
+ <item>
+ <p>In the <c><![CDATA[MatchBody]]></c> and
+ <c><![CDATA[MatchCondition]]></c> parts, only variables bound
+ previously can be used.</p>
+ </item>
+ <item>
+ <p>As a special case, the following apply in the
+ <c><![CDATA[MatchCondition/MatchBody]]></c> parts:</p>
+ <list type="bulleted">
+ <item>
+ <p>The variable <c><![CDATA['$_']]></c> expands to the whole
+ <seealso marker="#match_target">match target</seealso> term.
+ </p>
+ </item>
+ <item>
+ <p>The variable <c><![CDATA['$$']]></c> expands to a list of the
+ values of all bound variables in order (that is,
+ <c><![CDATA[['$1','$2', ...]]]></c>).</p>
+ </item>
+ </list>
+ </item>
+ </list>
+
+ <p>In the <c><![CDATA[MatchHead]]></c> part, all literals (except the
+ variables above) are interpreted "as is".</p>
+
+ <p>In the <c><![CDATA[MatchCondition/MatchBody]]></c> parts, the
+ interpretation is in some ways different. Literals in these parts
+ can either be written "as is", which works for all literals except
+ tuples, or by using the special form <c><![CDATA[{const, T}]]></c>,
+ where <c><![CDATA[T]]></c> is any Erlang term.</p>
+
+ <p>For tuple literals in the match specification, double tuple parentheses
+ can also be used, that is, construct them as a tuple of
arity one containing a single tuple, which is the one to be
constructed. The "double tuple parenthesis" syntax is useful to
construct tuples from already bound variables, like in
- <c><![CDATA[{{'$1', [a,b,'$2']}}]]></c>. Some examples may be needed:
- </p>
+ <c><![CDATA[{{'$1', [a,b,'$2']}}]]></c>. Examples:</p>
+
<table>
<row>
- <cell align="left" valign="middle">Expression </cell>
- <cell align="left" valign="middle">Variable bindings </cell>
- <cell align="left" valign="middle">Result </cell>
+ <cell align="left" valign="middle"><em>Expression</em></cell>
+ <cell align="left" valign="middle"><em>Variable Bindings</em></cell>
+ <cell align="left" valign="middle"><em>Result</em></cell>
</row>
<row>
- <cell align="left" valign="middle">{{'$1','$2'}} </cell>
+ <cell align="left" valign="middle">{{'$1','$2'}}</cell>
<cell align="left" valign="middle">'$1' = a, '$2' = b</cell>
<cell align="left" valign="middle">{a,b}</cell>
</row>
<row>
- <cell align="left" valign="middle">{const, {'$1', '$2'}} </cell>
- <cell align="left" valign="middle">doesn't matter</cell>
+ <cell align="left" valign="middle">{const, {'$1', '$2'}}</cell>
+ <cell align="left" valign="middle">Irrelevant</cell>
<cell align="left" valign="middle">{'$1', '$2'}</cell>
</row>
<row>
- <cell align="left" valign="middle">a </cell>
- <cell align="left" valign="middle">doesn't matter </cell>
+ <cell align="left" valign="middle">a</cell>
+ <cell align="left" valign="middle">Irrelevant</cell>
<cell align="left" valign="middle">a</cell>
</row>
<row>
- <cell align="left" valign="middle">'$1' </cell>
- <cell align="left" valign="middle">'$1' = [] </cell>
+ <cell align="left" valign="middle">'$1'</cell>
+ <cell align="left" valign="middle">'$1' = []</cell>
<cell align="left" valign="middle">[]</cell>
</row>
<row>
- <cell align="left" valign="middle">['$1'] </cell>
- <cell align="left" valign="middle">'$1' = [] </cell>
+ <cell align="left" valign="middle">['$1']</cell>
+ <cell align="left" valign="middle">'$1' = []</cell>
<cell align="left" valign="middle">[[]]</cell>
</row>
<row>
- <cell align="left" valign="middle">[{{a}}] </cell>
- <cell align="left" valign="middle">doesn't matter</cell>
+ <cell align="left" valign="middle">[{{a}}]</cell>
+ <cell align="left" valign="middle">Irrelevant</cell>
<cell align="left" valign="middle">[{a}]</cell>
</row>
<row>
- <cell align="left" valign="middle">42 </cell>
- <cell align="left" valign="middle">doesn't matter</cell>
+ <cell align="left" valign="middle">42</cell>
+ <cell align="left" valign="middle">Irrelevant</cell>
<cell align="left" valign="middle">42</cell>
</row>
<row>
- <cell align="left" valign="middle">"hello" </cell>
- <cell align="left" valign="middle">doesn't matter</cell>
+ <cell align="left" valign="middle">"hello"</cell>
+ <cell align="left" valign="middle">Irrelevant</cell>
<cell align="left" valign="middle">"hello"</cell>
</row>
<row>
- <cell align="left" valign="middle">$1 </cell>
- <cell align="left" valign="middle">doesn't matter</cell>
- <cell align="left" valign="middle">49 (the ASCII value for the character '1')</cell>
+ <cell align="left" valign="middle">$1</cell>
+ <cell align="left" valign="middle">Irrelevant</cell>
+ <cell align="left" valign="middle">49 (the ASCII value for
+ character '1')</cell>
</row>
- <tcaption>Literals in the MatchCondition/MatchBody parts of a match_spec</tcaption>
+ <tcaption>Literals in MatchCondition/MatchBody Parts of a Match
+ Specification</tcaption>
</table>
</section>
<section>
- <title>Execution of the match</title>
+ <title>Execution of the Match</title>
<p>The execution of the match expression, when the runtime system
- decides whether a trace message should be sent, goes as follows:
- </p>
- <p>For each tuple in the <c><![CDATA[MatchExpression]]></c> list and while no
- match has succeeded:</p>
- <list type="bulleted">
- <item>Match the <c><![CDATA[MatchHead]]></c> part against the arguments to the
- function,
- binding the <c><![CDATA['$<number>']]></c> variables (much like in
- <c><![CDATA[ets:match/2]]></c>).
- If the <c><![CDATA[MatchHead]]></c> cannot match the arguments, the match fails.
- </item>
- <item>Evaluate each <c><![CDATA[MatchCondition]]></c> (where only
- <c><![CDATA['$<number>']]></c> variables previously bound in the
- <c><![CDATA[MatchHead]]></c> can occur) and expect it to return the atom
- <c><![CDATA[true]]></c>. As soon as a condition does not evaluate to
- <c><![CDATA[true]]></c>, the match fails. If any BIF call generates an
- exception, also fail.
+ decides whether a trace message is to be sent, is as follows:</p>
+
+ <p>For each tuple in the <c><![CDATA[MatchExpression]]></c> list and while
+ no match has succeeded:</p>
+
+ <list type="ordered">
+ <item>
+ <p>Match the <c><![CDATA[MatchHead]]></c> part against the match target
+ term, binding the <c><![CDATA['$<number>']]></c> variables
+ (much like in <c><![CDATA[ets:match/2]]></c>). If the
+ <c><![CDATA[MatchHead]]></c> part cannot match the arguments, the
+ match fails.</p>
</item>
<item>
+ <p>Evaluate each <c><![CDATA[MatchCondition]]></c> (where only
+ <c><![CDATA['$<number>']]></c> variables previously bound in the
+ <c><![CDATA[MatchHead]]></c> part can occur) and expect it to return
+ the atom <c><![CDATA[true]]></c>. When a condition does not evaluate
+ to <c><![CDATA[true]]></c>, the match fails. If any BIF call
+ generates an exception, the match also fails.</p>
+ </item>
+ <item>
+ <p>Two cases can occur:</p>
<list type="bulleted">
- <item><em>If the match_spec is executing when tracing:</em><br></br>
- Evaluate each <c><![CDATA[ActionTerm]]></c> in the same way as the
- <c><![CDATA[MatchConditions]]></c>, but completely ignore the return
- values. Regardless of what happens in this part, the match has
- succeeded.</item>
- <item><em>If the match_spec is executed when selecting objects from an ETS table:</em><br></br>
- Evaluate the expressions in order and return the value of
- the last expression (typically there is only one expression
- in this context)</item>
+ <item>
+ <p>If the match specification is executing when tracing:</p>
+ <p>Evaluate each <c><![CDATA[ActionTerm]]></c> in the same way as
+ the <c><![CDATA[MatchConditions]]></c>, but ignore the return
+ values. Regardless of what happens in this part, the match has
+ succeeded.</p>
+ </item>
+ <item>
+ <p>If the match specification is executed when selecting objects
+ from an <c>ets</c> table:</p>
+ <p>Evaluate the expressions in order and return the value of
+ the last expression (typically there is only one expression
+ in this context).</p>
+ </item>
</list>
</item>
</list>
</section>
<section>
- <title>Differences between match specifications in ETS and tracing</title>
- <p>ETS match specifications are there to produce a return
- value. Usually the <c><![CDATA[MatchBody]]></c> contains one single
- <c><![CDATA[ConditionExpression]]></c> which defines the return value without having
- any side effects. Calls with side effects are not allowed in the
- ETS context.</p>
+ <marker id="differences_ets_tracing"/>
+ <title>Differences between Match Specifications in ETS and Tracing</title>
+ <p><c>ets</c> match specifications produce a return value.
+ Usually the <c><![CDATA[MatchBody]]></c> contains one single
+ <c><![CDATA[ConditionExpression]]></c> that defines the return value
+ without any side effects. Calls with side effects are not allowed in
+ the <c>ets</c> context.</p>
+
<p>When tracing there is no return value to produce, the
- match specification either matches or doesn't. The effect when the
- expression matches is a trace message rather then a returned
- term. The <c><![CDATA[ActionTerm]]></c>'s are executed as in an imperative
- language, i.e. for their side effects. Functions with side effects
+ match specification either matches or does not. The effect when the
+ expression matches is a trace message rather than a returned
+ term. The <c><![CDATA[ActionTerm]]></c>s are executed as in an imperative
+ language, that is, for their side effects. Functions with side effects
are also allowed when tracing.</p>
- <p>In ETS the match head is a <c><![CDATA[tuple()]]></c> (or a single match
- variable) while it is a list (or a single match variable) when
- tracing.</p>
</section>
<section>
- <title>Examples</title>
- <p>Match an argument list of three where the first and third arguments
+ <title>Tracing Examples</title>
+ <p>Match an argument list of three, where the first and third arguments
are equal:</p>
+
<code type="none"><![CDATA[
[{['$1', '_', '$1'],
[],
[]}]
]]></code>
- <p>Match an argument list of three where the second argument is
- a number greater than three:</p>
+
+ <p>Match an argument list of three, where the second argument is
+ a number &gt; 3:</p>
+
<code type="none"><![CDATA[
[{['_', '$1', '_'],
[{ '>', '$1', 3}],
[]}]
]]></code>
- <p>Match an argument list of three, where the third argument
- is a tuple containing argument one and two <em>or</em> a list
- beginning with argument one and two (i. e. <c><![CDATA[[a,b,[a,b,c]]]]></c> or
- <c><![CDATA[[a,b,{a,b}]]]></c>):
- </p>
+
+ <p>Match an argument list of three, where the third argument is
+ either a tuple containing argument one and two, <em>or</em> a list
+ beginning with argument one and two (that is,
+ <c><![CDATA[[a,b,[a,b,c]]]]></c> or <c><![CDATA[[a,b,{a,b}]]]></c>):</p>
+
<code type="none"><![CDATA[
[{['$1', '$2', '$3'],
- [{orelse,
+ [{'orelse',
{'=:=', '$3', {{'$1','$2'}}},
{'and',
{'=:=', '$1', {hd, '$3'}},
{'=:=', '$2', {hd, {tl, '$3'}}}}}],
[]}]
]]></code>
- <p>The above problem may also be solved like this:</p>
+
+ <p>The above problem can also be solved as follows:</p>
+
<code type="none"><![CDATA[
[{['$1', '$2', {'$1', '$2}], [], []},
{['$1', '$2', ['$1', '$2' | '_']], [], []}]
]]></code>
- <p>Match two arguments where the first is a tuple beginning with
- a list which in turn begins with the second argument times
- two (i. e. [{[4,x],y},2] or [{[8], y, z},4])</p>
+
+ <p>Match two arguments, where the first is a tuple beginning with
+ a list that in turn begins with the second argument times
+ two (that is, <c>[{[4,x],y},2]</c> or <c>[{[8], y, z},4])</c>:</p>
+
<code type="none"><![CDATA[
[{['$1', '$2'],[{'=:=', {'*', 2, '$2'}, {hd, {element, 1, '$1'}}}],
[]}]
]]></code>
+
<p>Match three arguments. When all three are equal and are
- numbers, append the process dump to the trace message, else
- let the trace message be as is, but set the sequential trace
- token label to 4711.</p>
+ numbers, append the process dump to the trace message, otherwise
+ let the trace message be "as is", but set the sequential trace
+ token label to 4711:</p>
+
<code type="none"><![CDATA[
[{['$1', '$1', '$1'],
[{is_number, '$1'}],
[{message, {process_dump}}]},
{'_', [], [{set_seq_token, label, 4711}]}]
]]></code>
- <p>As can be noted above, the parameter list can be matched
- against a single <c><![CDATA[MatchVariable]]></c> or an <c><![CDATA['_']]></c>. To replace the
- whole
- parameter list with a single variable is a special case. In all
- other cases the <c><![CDATA[MatchHead]]></c> has to be a <em>proper</em> list.
- </p>
- <p>Match all objects in an ets table where the first element is
- the atom 'strider' and the tuple arity is 3 and return the whole
- object.</p>
+
+ <p>As can be noted above, the parameter list can be matched against a
+ single <c><![CDATA[MatchVariable]]></c> or an <c><![CDATA['_']]></c>.
+ To replace the whole parameter list with a single variable is a special
+ case. In all other cases the <c><![CDATA[MatchHead]]></c> must be a
+ <em>proper</em> list.</p>
+
+ <p>Generate a trace message only if the trace control word is set to 1:</p>
+
+ <code type="none"><![CDATA[
+[{'_',
+ [{'==',{get_tcw},{const, 1}}],
+ []}]
+ ]]></code>
+
+ <p>Generate a trace message only if there is a <c>seq_trace</c> token:</p>
+
+ <code type="none"><![CDATA[
+[{'_',
+ [{'==',{is_seq_trace},{const, 1}}],
+ []}]
+ ]]></code>
+
+ <p>Remove the <c>'silent'</c> trace flag when the first argument is
+ <c>'verbose'</c>, and add it when it is <c>'silent':</c></p>
+
+ <code type="none"><![CDATA[
+[{'$1',
+ [{'==',{hd, '$1'},verbose}],
+ [{trace, [silent],[]}]},
+ {'$1',
+ [{'==',{hd, '$1'},silent}],
+ [{trace, [],[silent]}]}]
+ ]]></code>
+
+ <p>Add a <c>return_trace</c> message if the function is of arity 3:</p>
+
+ <code type="none"><![CDATA[
+[{'$1',
+ [{'==',{length, '$1'},3}],
+ [{return_trace}]},
+ {'_',[],[]}]
+ ]]></code>
+
+ <p>Generate a trace message only if the function is of arity 3 and the
+ first argument is <c>'trace'</c>:</p>
+
+ <code type="none"><![CDATA[
+[{['trace','$2','$3'],
+ [],
+ []},
+ {'_',[],[]}]
+ ]]></code>
+ </section>
+
+ <section>
+ <title>ETS Examples</title>
+ <p>Match all objects in an <c>ets</c> table, where the first element is
+ the atom <c>'strider'</c> and the tuple arity is 3, and return the whole
+ object:</p>
+
<code type="none"><![CDATA[
[{{strider,'_','_'},
[],
['$_']}]
]]></code>
- <p>Match all objects in an ets table with arity &gt; 1 and the first
- element is 'gandalf', return element 2.</p>
+
+ <p>Match all objects in an <c>ets</c> table with arity &gt; 1 and the first
+ element is 'gandalf', and return element 2:</p>
+
<code type="none"><![CDATA[
[{'$1',
[{'==', gandalf, {element, 1, '$1'}},{'>=',{size, '$1'},2}],
[{element,2,'$1'}]}]
]]></code>
- <p>In the above example, if the first element had been the key,
- it's much more efficient to match that key in the <c><![CDATA[MatchHead]]></c>
- part than in the <c><![CDATA[MatchConditions]]></c> part. The search space of
- the tables is restricted with regards to the <c><![CDATA[MatchHead]]></c> so
- that only objects with the matching key are searched.
- </p>
- <p>Match tuples of 3 elements where the second element is either
- 'merry' or 'pippin', return the whole objects.</p>
+
+ <p>In this example, if the first element had been the key, it is
+ much more efficient to match that key in the <c><![CDATA[MatchHead]]></c>
+ part than in the <c><![CDATA[MatchConditions]]></c> part.
+ The search space of the tables is restricted with regards to the
+ <c><![CDATA[MatchHead]]></c> so
+ that only objects with the matching key are searched.</p>
+
+ <p>Match tuples of three elements, where the second element is either
+ <c>'merry'</c> or <c>'pippin'</c>, and return the whole objects:</p>
+
<code type="none"><![CDATA[
[{{'_',merry,'_'},
[],
@@ -613,8 +861,9 @@
[],
['$_']}]
]]></code>
- <p>The function <c><![CDATA[ets:test_ms/2]]></c> can be useful for testing
- complicated ets matches.</p>
+
+ <p>Function <seealso marker="stdlib:ets#test_ms/2"><c>ets:test_ms/2></c></seealso>
+ can be useful for testing complicated <c>ets</c> matches.</p>
</section>
</chapter>