diff options
Diffstat (limited to 'system/doc/reference_manual/macros.xml')
-rw-r--r-- | system/doc/reference_manual/macros.xml | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/system/doc/reference_manual/macros.xml b/system/doc/reference_manual/macros.xml new file mode 100644 index 0000000000..a1ba182eff --- /dev/null +++ b/system/doc/reference_manual/macros.xml @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2003</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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 online 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. + + </legalnotice> + + <title>The Preprocessor</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>macros.xml</file> + </header> + + <section> + <title>File Inclusion</title> + <p>A file can be included in the following way:</p> + <pre> +-include(File). +-include_lib(File).</pre> + <p><c>File</c>, a string, should point out a file. The contents of + this file are included as-is, at the position of the directive.</p> + <p>Include files are typically used for record and macro + definitions that are shared by several modules. It is + recommended that the file name extension <c>.hrl</c> be used + for include files.</p> + <p><c>File</c> may start with a path component <c>$VAR</c>, for + some string <c>VAR</c>. If that is the case, the value of + the environment variable <c>VAR</c> as returned by + <c>os:getenv(VAR)</c> is substituted for <c>$VAR</c>. If + <c>os:getenv(VAR)</c> returns <c>false</c>, <c>$VAR</c> is left + as is.</p> + <p>If the filename <c>File</c> is absolute (possibly after + variable substitution), the include file with that name is + included. Otherwise, the specified file is searched for in + the current working directory, in the same directory as + the module being compiled, and in the directories given by + the <c>include</c> option, in that order. + See <c>erlc(1)</c> and <c>compile(3)</c> for details.</p> + <p>Examples:</p> + <pre> +-include("my_records.hrl"). +-include("incdir/my_records.hrl"). +-include("/home/user/proj/my_records.hrl"). +-include("$PROJ_ROOT/my_records.hrl").</pre> + <p><c>include_lib</c> is similar to <c>include</c>, but should not + point out an absolute file. Instead, the first path component + (possibly after variable substitution) is assumed to be + the name of an application. Example:</p> + <pre> +-include_lib("kernel/include/file.hrl").</pre> + <p>The code server uses <c>code:lib_dir(kernel)</c> to find + the directory of the current (latest) version of Kernel, and + then the subdirectory <c>include</c> is searched for the file + <c>file.hrl</c>.</p> + </section> + + <section> + <title>Defining and Using Macros</title> + <p>A macro is defined the following way:</p> + <code type="none"> +-define(Const, Replacement). +-define(Func(Var1,...,VarN), Replacement).</code> + <p>A macro definition can be placed anywhere among the attributes + and function declarations of a module, but the definition must + come before any usage of the macro.</p> + <p>If a macro is used in several modules, it is recommended that + the macro definition is placed in an include file.</p> + <p>A macro is used the following way:</p> + <code type="none"> +?Const +?Func(Arg1,...,ArgN)</code> + <p>Macros are expanded during compilation. A simple macro + <c>?Const</c> will be replaced with <c>Replacement</c>. + Example:</p> + <code type="none"> +-define(TIMEOUT, 200). +... +call(Request) -> + server:call(refserver, Request, ?TIMEOUT).</code> + <p>This will be expanded to:</p> + <code type="none"> +call(Request) -> + server:call(refserver, Request, 200).</code> + <p>A macro <c>?Func(Arg1,...,ArgN)</c> will be replaced with + <c>Replacement</c>, where all occurrences of a variable <c>Var</c> + from the macro definition are replaced with the corresponding + argument <c>Arg</c>. Example:</p> + <code type="none"> +-define(MACRO1(X, Y), {a, X, b, Y}). +... +bar(X) -> + ?MACRO1(a, b), + ?MACRO1(X, 123)</code> + <p>This will be expanded to:</p> + <code type="none"> +bar(X) -> + {a,a,b,b}, + {a,X,b,123}.</code> + <p>It is good programming practice, but not mandatory, to ensure + that a macro definition is a valid Erlang syntactic form.</p> + <p>To view the result of macro expansion, a module can be compiled + with the <c>'P'</c> option. <c>compile:file(File, ['P'])</c>. + This produces a listing of the parsed code after preprocessing + and parse transforms, in the file <c>File.P</c>.</p> + </section> + + <section> + <title>Predefined Macros</title> + <p>The following macros are predefined:</p> + <taglist> + <tag><c>?MODULE</c></tag> + <item>The name of the current module.</item> + <tag><c>?MODULE_STRING</c>.</tag> + <item>The name of the current module, as a string.</item> + <tag><c>?FILE</c>.</tag> + <item>The file name of the current module.</item> + <tag><c>?LINE</c>.</tag> + <item>The current line number.</item> + <tag><c>?MACHINE</c>.</tag> + <item>The machine name, <c>'BEAM'</c>.</item> + </taglist> + </section> + + <section> + <title>Flow Control in Macros</title> + <p>The following macro directives are supplied:</p> + <taglist> + <tag><c>-undef(Macro).</c></tag> + <item>Causes the macro to behave as if it had never been defined.</item> + <tag><c>-ifdef(Macro).</c></tag> + <item>Evaluate the following lines only if <c>Macro</c> is + defined.</item> + <tag><c>-ifndef(Macro).</c></tag> + <item>Evaluate the following lines only if <c>Macro</c> is not + defined.</item> + <tag><c>-else.</c></tag> + <item>Only allowed after an <c>ifdef</c> or <c>ifndef</c> + directive. If that condition was false, the lines following + <c>else</c> are evaluated instead.</item> + <tag><c>-endif.</c></tag> + <item>Specifies the end of an <c>ifdef</c> or <c>ifndef</c> + directive.</item> + </taglist> + <note> + <p>The macro directives cannot be used inside functions.</p> + </note> + <p>Example:</p> + <code type="none"> +-module(m). +... + +-ifdef(debug). +-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])). +-else. +-define(LOG(X), true). +-endif. + +...</code> + <p>When trace output is desired, <c>debug</c> should be defined + when the module <c>m</c> is compiled:</p> + <pre> +% <input>erlc -Ddebug m.erl</input> + +or + +1> <input>c(m, {d, debug}).</input> +{ok,m}</pre> + <p><c>?LOG(Arg)</c> will then expand to a call to <c>io:format/2</c> + and provide the user with some simple trace output.</p> + </section> + + <section> + <title>Stringifying Macro Arguments</title> + <p>The construction <c>??Arg</c>, where <c>Arg</c> is a macro + argument, will be expanded to a string containing the tokens of + the argument. This is similar to the <c>#arg</c> stringifying + construction in C.</p> + <p>The feature was added in Erlang 5.0/OTP R7.</p> + <p>Example:</p> + <code type="none"> +-define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])). + +?TESTCALL(myfunction(1,2)), +?TESTCALL(you:function(2,1)).</code> + <p>results in</p> + <code type="none"> +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)]).</code> + <p>That is, a trace output with both the function called and + the resulting value.</p> + </section> +</chapter> + |