1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- This document was generated using DocBuilder 3.3.3 -->
<HTML>
<HEAD>
<TITLE>Macros</TITLE>
<SCRIPT type="text/javascript" src="../../doc/erlresolvelinks.js">
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF"
ALINK="#FF0000">
<CENTER>
<A HREF="http://www.erlang.se"><IMG BORDER=0 ALT="[Ericsson AB]" SRC="min_head.gif"></A>
</CENTER>
<A NAME="7"><!-- Empty --></A>
<H2>7 Macros</H2>
<A NAME="7.1"><!-- Empty --></A>
<H3>7.1 Defining and Using Macros</H3>
<P>A macro is defined the following way:
<PRE>
-define(Const, Replacement).
-define(Func(Var1,...,VarN), Replacement).
</PRE>
<P>A macro definition can be placed anyhere among the attributes
and function declarations of a module, but the definition must
come before any usage of the macro.
<P>If a macro is used in several modules, it is recommended that
the macro definition is placed in an include file.
<P>A macro is used the following way:
<PRE>
?Const
?Func(Arg1,...,ArgN)
</PRE>
<P>Macros are expanded during compilation. A simple macro
<CODE>?Const</CODE> will be replaced with <CODE>Replacement</CODE>.
Example:
<PRE>
-define(TIMEOUT, 200).
...
call(Request) ->
server:call(refserver, Request, ?TIMEOUT).
</PRE>
<P>This will be expanded to:
<PRE>
call(Request) ->
server:call(refserver, Request, 200).
</PRE>
<P>A macro <CODE>?Func(Arg1,...,ArgN)</CODE> will be replaced with
<CODE>Replacement</CODE>, where all occurences of a variable <CODE>Var</CODE>
from the macro definition are replaced with the corresponding
argument <CODE>Arg</CODE>. Example:
<PRE>
-define(MACRO1(X, Y), {a, X, b, Y}).
...
bar(X) ->
?MACRO1(a, b),
?MACRO1(X, 123)
</PRE>
<P>This will be expanded to:
<PRE>
bar(X) ->
{a,a,b,b},
{a,X,b,123}.
</PRE>
<P>It is good programming practice, but not mandatory, to ensure
that a macro definition is a valid Erlang syntactic form.
<P>To view the result of macro expansion, a module can be compiled
with the <CODE>'P'</CODE> option. <CODE>compile:file(File, ['P'])</CODE>.
This produces a listing of the parsed code after preprocessing
and parse transforms, in the file <CODE>File.P</CODE>.
<A NAME="7.2"><!-- Empty --></A>
<H3>7.2 Predefined Macros</H3>
<P>The following macros are predefined:
<P>
<DL>
<DT>
<CODE>?MODULE</CODE>
</DT>
<DD>
The name of the current module.
</DD>
<DT>
<CODE>?MODULE_STRING</CODE>.
</DT>
<DD>
The name of the current module, as a string.
</DD>
<DT>
<CODE>?FILE</CODE>.
</DT>
<DD>
The file name of the current module.
</DD>
<DT>
<CODE>?LINE</CODE>.
</DT>
<DD>
The current line number.
</DD>
<DT>
<CODE>?MACHINE</CODE>.
</DT>
<DD>
The machine name, <CODE>'BEAM'</CODE>.
</DD>
</DL>
<A NAME="7.3"><!-- Empty --></A>
<H3>7.3 Flow Control in Macros</H3>
<P>The following macro directives are supplied:
<P>
<DL>
<DT>
<CODE>-undef(Macro).</CODE>
</DT>
<DD>
Causes the macro to behave as if it had never been defined.
</DD>
<DT>
<CODE>-ifdef(Macro).</CODE>
</DT>
<DD>
Evaluate the following lines only if <CODE>Macro</CODE> is
defined.
</DD>
<DT>
<CODE>-ifndef(Macro).</CODE>
</DT>
<DD>
Evaluate the following lines only if <CODE>Macro</CODE> is not
defined.
</DD>
<DT>
<CODE>-else.</CODE>
</DT>
<DD>
Only allowed after an <CODE>ifdef</CODE> or <CODE>ifndef</CODE>
directive. If that condition was false, the lines following
<CODE>else</CODE> are evaluated instead.
</DD>
<DT>
<CODE>-endif.</CODE>
</DT>
<DD>
Specifies the end of an <CODE>ifdef</CODE> or <CODE>ifndef</CODE>
directive.
</DD>
</DL>
<P>Example:
<PRE>
-module(m).
...
-ifdef(debug).
-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).
-else.
-define(LOG(X), true).
-endif.
...
</PRE>
<P>When trace output is desired, <CODE>debug</CODE> should be defined
when the module <CODE>m</CODE> is compiled:
<PRE>
% <STRONG>erlc -Ddebug m.erl</STRONG>
or
1> <STRONG>c(m, {d, debug}).</STRONG>
{ok,m}
</PRE>
<P><CODE>?LOG(Arg)</CODE> will then expand to a call to <CODE>io:format/2</CODE>
and provide the user with some simple trace output.<A NAME="7.4"><!-- Empty --></A>
<H3>7.4 Stringifying Macro Arguments</H3>
<P>The construction <CODE>??Arg</CODE>, where <CODE>Arg</CODE> is a macro
argument, will be expanded to a string containing the tokens of
the argument. This is similar to the <CODE>#arg</CODE> stringifying
construction in C.
<P>The feature was added in Erlang 5.0/OTP R7.
<P>Example:
<PRE>
-define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).
?TESTCALL(myfunction(1,2)),
?TESTCALL(you:function(2,1)).
</PRE>
<P>results in
<PRE>
io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",m:myfunction(1,2)]),
io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).
</PRE>
<P>That is, a trace output with both the function called and
the resulting value.<CENTER>
<HR>
<SMALL>
Copyright © 1991-2006
<A HREF="http://www.erlang.se">Ericsson AB</A><BR>
</SMALL>
</CENTER>
</BODY>
</HTML>
|