<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html xmlns:fn="http://www.w3.org/2005/02/xpath-functions"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" href="../otp_doc.css" type="text/css"> <title>Erlang -- The Preprocessor</title> </head> <body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container"> <script id="js" type="text/javascript" language="JavaScript" src="../js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript"> <!-- function getWinHeight() { var myHeight = 0; if( typeof( window.innerHeight ) == 'number' ) { //Non-IE myHeight = window.innerHeight; } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { //IE 6+ in 'standards compliant mode' myHeight = document.documentElement.clientHeight; } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { //IE 4 compatible myHeight = document.body.clientHeight; } return myHeight; } function setscrollpos() { var objf=document.getElementById('loadscrollpos'); document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2; } function addEvent(obj, evType, fn){ if (obj.addEventListener){ obj.addEventListener(evType, fn, true); return true; } else if (obj.attachEvent){ var r = obj.attachEvent("on"+evType, fn); return r; } else { return false; } } addEvent(window, 'load', setscrollpos); //--></script><div id="leftnav"><div class="innertube"> <img alt="Erlang logo" src="../erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="../pdf/otp-system-documentation-5.9.3.1.pdf">PDF</a><br><a href="../index.html">Top</a></small><p><strong>Erlang Reference Manual</strong><br><strong>User's Guide</strong><br><small>Version 5.9.3.1</small></p> <br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p> <ul class="flipMenu" imagepath="../js/flipmenu"> <li id="no" title="Introduction" expanded="false">Introduction<ul> <li><a href="introduction.html"> Top of chapter </a></li> <li title="Purpose"><a href="introduction.html#id73748">Purpose</a></li> <li title="Prerequisites"><a href="introduction.html#id66106">Prerequisites</a></li> <li title="Document Conventions"><a href="introduction.html#id67296">Document Conventions</a></li> <li title="Complete List of BIFs"><a href="introduction.html#id68121">Complete List of BIFs</a></li> <li title="Reserved Words"><a href="introduction.html#id60679">Reserved Words</a></li> <li title="Character Set"><a href="introduction.html#id61758">Character Set</a></li> </ul> </li> <li id="no" title="Data Types" expanded="false">Data Types<ul> <li><a href="data_types.html"> Top of chapter </a></li> <li title="Terms"><a href="data_types.html#id63330">Terms</a></li> <li title="Number"><a href="data_types.html#id68697">Number</a></li> <li title="Atom"><a href="data_types.html#id62285">Atom</a></li> <li title="Bit Strings and Binaries"><a href="data_types.html#id68011">Bit Strings and Binaries</a></li> <li title="Reference"><a href="data_types.html#id58120">Reference</a></li> <li title="Fun"><a href="data_types.html#id67499">Fun</a></li> <li title="Port Identifier"><a href="data_types.html#id69290">Port Identifier</a></li> <li title="Pid"><a href="data_types.html#id60853">Pid</a></li> <li title="Tuple"><a href="data_types.html#id73719">Tuple</a></li> <li title="List"><a href="data_types.html#id73198">List</a></li> <li title="String"><a href="data_types.html#id68626">String</a></li> <li title="Record"><a href="data_types.html#id65682">Record</a></li> <li title="Boolean"><a href="data_types.html#id67471">Boolean</a></li> <li title="Escape Sequences"><a href="data_types.html#id73885">Escape Sequences</a></li> <li title="Type Conversions"><a href="data_types.html#id69219">Type Conversions</a></li> </ul> </li> <li id="no" title="Pattern Matching" expanded="false">Pattern Matching<ul> <li><a href="patterns.html"> Top of chapter </a></li> <li title="Pattern Matching"><a href="patterns.html#id68202">Pattern Matching</a></li> </ul> </li> <li id="no" title="Modules" expanded="false">Modules<ul> <li><a href="modules.html"> Top of chapter </a></li> <li title="Module Syntax"><a href="modules.html#id68326">Module Syntax</a></li> <li title="Module Attributes"><a href="modules.html#id68358">Module Attributes</a></li> <li title="Comments"><a href="modules.html#id74337">Comments</a></li> <li title="The module_info/0 and module_info/1 functions"><a href="modules.html#id74350">The module_info/0 and module_info/1 functions</a></li> </ul> </li> <li id="no" title="Functions" expanded="false">Functions<ul> <li><a href="functions.html"> Top of chapter </a></li> <li title="Function Declaration Syntax"><a href="functions.html#id74609">Function Declaration Syntax</a></li> <li title="Function Evaluation"><a href="functions.html#id74724">Function Evaluation</a></li> <li title="Tail recursion"><a href="functions.html#id74875">Tail recursion</a></li> <li title="Built-In Functions, BIFs"><a href="functions.html#id74908">Built-In Functions, BIFs</a></li> </ul> </li> <li id="no" title="Types and Function Specifications" expanded="false">Types and Function Specifications<ul> <li><a href="typespec.html"> Top of chapter </a></li> <li title="Introduction of Types"><a href="typespec.html#id75024">Introduction of Types</a></li> <li title="Types and their Syntax"><a href="typespec.html#id75072">Types and their Syntax</a></li> <li title="Type declarations of user-defined types"><a href="typespec.html#id75688">Type declarations of user-defined types</a></li> <li title="Type information in record declarations"><a href="typespec.html#id75770">Type information in record declarations</a></li> <li title="Specifications for functions"><a href="typespec.html#id75847">Specifications for functions</a></li> </ul> </li> <li id="no" title="Expressions" expanded="false">Expressions<ul> <li><a href="expressions.html"> Top of chapter </a></li> <li title="Expression Evaluation"><a href="expressions.html#id76067">Expression Evaluation</a></li> <li title="Terms"><a href="expressions.html#id76110">Terms</a></li> <li title="Variables"><a href="expressions.html#id76122">Variables</a></li> <li title="Patterns"><a href="expressions.html#id76253">Patterns</a></li> <li title="Match"><a href="expressions.html#id76372">Match</a></li> <li title="Function Calls"><a href="expressions.html#id76431">Function Calls</a></li> <li title="If"><a href="expressions.html#id76631">If</a></li> <li title="Case"><a href="expressions.html#id76696">Case</a></li> <li title="Send"><a href="expressions.html#id76761">Send</a></li> <li title="Receive"><a href="expressions.html#id76844">Receive</a></li> <li title="Term Comparisons"><a href="expressions.html#id77009">Term Comparisons</a></li> <li title="Arithmetic Expressions"><a href="expressions.html#id77270">Arithmetic Expressions</a></li> <li title="Boolean Expressions"><a href="expressions.html#id77776">Boolean Expressions</a></li> <li title="Short-Circuit Expressions"><a href="expressions.html#id77931">Short-Circuit Expressions</a></li> <li title="List Operations"><a href="expressions.html#id78047">List Operations</a></li> <li title="Bit Syntax Expressions"><a href="expressions.html#id78116">Bit Syntax Expressions</a></li> <li title="Fun Expressions"><a href="expressions.html#id78658">Fun Expressions</a></li> <li title="Catch and Throw"><a href="expressions.html#id78840">Catch and Throw</a></li> <li title="Try"><a href="expressions.html#id78986">Try</a></li> <li title="Parenthesized Expressions"><a href="expressions.html#id79344">Parenthesized Expressions</a></li> <li title="Block Expressions"><a href="expressions.html#id79376">Block Expressions</a></li> <li title="List Comprehensions"><a href="expressions.html#id79401">List Comprehensions</a></li> <li title="Bit String Comprehensions"><a href="expressions.html#id79541">Bit String Comprehensions</a></li> <li title="Guard Sequences"><a href="expressions.html#id79673">Guard Sequences</a></li> <li title="Operator Precedence"><a href="expressions.html#id80211">Operator Precedence</a></li> </ul> </li> <li id="loadscrollpos" title="The Preprocessor" expanded="true">The Preprocessor<ul> <li><a href="macros.html"> Top of chapter </a></li> <li title="File Inclusion"><a href="macros.html#id80530">File Inclusion</a></li> <li title="Defining and Using Macros"><a href="macros.html#id80659">Defining and Using Macros</a></li> <li title="Predefined Macros"><a href="macros.html#id80782">Predefined Macros</a></li> <li title="Macros Overloading"><a href="macros.html#id80850">Macros Overloading</a></li> <li title="Flow Control in Macros"><a href="macros.html#id80919">Flow Control in Macros</a></li> <li title="Stringifying Macro Arguments"><a href="macros.html#id81056">Stringifying Macro Arguments</a></li> </ul> </li> <li id="no" title="Records" expanded="false">Records<ul> <li><a href="records.html"> Top of chapter </a></li> <li title="Defining Records"><a href="records.html#id81178">Defining Records</a></li> <li title="Creating Records"><a href="records.html#id81209">Creating Records</a></li> <li title="Accessing Record Fields"><a href="records.html#id81264">Accessing Record Fields</a></li> <li title="Updating Records"><a href="records.html#id81303">Updating Records</a></li> <li title="Records in Guards"><a href="records.html#id81336">Records in Guards</a></li> <li title="Records in Patterns"><a href="records.html#id81368">Records in Patterns</a></li> <li title="Nested records"><a href="records.html#id81395">Nested records</a></li> <li title="Internal Representation of Records"><a href="records.html#id81430">Internal Representation of Records</a></li> </ul> </li> <li id="no" title="Errors and Error Handling" expanded="false">Errors and Error Handling<ul> <li><a href="errors.html"> Top of chapter </a></li> <li title="Terminology"><a href="errors.html#id81550">Terminology</a></li> <li title="Exceptions"><a href="errors.html#id81678">Exceptions</a></li> <li title="Handling of Run-Time Errors in Erlang"><a href="errors.html#id81851">Handling of Run-Time Errors in Erlang</a></li> <li title="Exit Reasons"><a href="errors.html#id81913">Exit Reasons</a></li> </ul> </li> <li id="no" title="Processes" expanded="false">Processes<ul> <li><a href="processes.html"> Top of chapter </a></li> <li title="Processes"><a href="processes.html#id82387">Processes</a></li> <li title="Process Creation"><a href="processes.html#id82400">Process Creation</a></li> <li title="Registered Processes"><a href="processes.html#id82449">Registered Processes</a></li> <li title="Process Termination"><a href="processes.html#id82560">Process Termination</a></li> <li title="Message Sending"><a href="processes.html#id82650">Message Sending</a></li> <li title="Links"><a href="processes.html#id82679">Links</a></li> <li title="Error Handling"><a href="processes.html#id82744">Error Handling</a></li> <li title="Monitors"><a href="processes.html#id82854">Monitors</a></li> <li title="Process Dictionary"><a href="processes.html#id82946">Process Dictionary</a></li> </ul> </li> <li id="no" title="Distributed Erlang" expanded="false">Distributed Erlang<ul> <li><a href="distributed.html"> Top of chapter </a></li> <li title="Distributed Erlang System"><a href="distributed.html#id83013">Distributed Erlang System</a></li> <li title="Nodes"><a href="distributed.html#id83044">Nodes</a></li> <li title="Node Connections"><a href="distributed.html#id83114">Node Connections</a></li> <li title="epmd"><a href="distributed.html#id83164">epmd</a></li> <li title="Hidden Nodes"><a href="distributed.html#id83184">Hidden Nodes</a></li> <li title="C Nodes"><a href="distributed.html#id83230">C Nodes</a></li> <li title="Security"><a href="distributed.html#id83254">Security</a></li> <li title="Distribution BIFs"><a href="distributed.html#id83364">Distribution BIFs</a></li> <li title="Distribution Command Line Flags"><a href="distributed.html#id83662">Distribution Command Line Flags</a></li> <li title="Distribution Modules"><a href="distributed.html#id83799">Distribution Modules</a></li> </ul> </li> <li id="no" title="Compilation and Code Loading" expanded="false">Compilation and Code Loading<ul> <li><a href="code_loading.html"> Top of chapter </a></li> <li title="Compilation"><a href="code_loading.html#id84002">Compilation</a></li> <li title="Code Loading"><a href="code_loading.html#id84112">Code Loading</a></li> <li title="Code Replacement"><a href="code_loading.html#id84159">Code Replacement</a></li> <li title="Running a function when a module is loaded"><a href="code_loading.html#id84234">Running a function when a module is loaded</a></li> </ul> </li> <li id="no" title="Ports and Port Drivers" expanded="false">Ports and Port Drivers<ul> <li><a href="ports.html"> Top of chapter </a></li> <li title="Ports"><a href="ports.html#id84374">Ports</a></li> <li title="Port Drivers"><a href="ports.html#id84409">Port Drivers</a></li> <li title="Port BIFs"><a href="ports.html#id84449">Port BIFs</a></li> </ul> </li> </ul> </div></div> <div id="content"> <div class="innertube"> <h1>8 The Preprocessor</h1> <h3><a name="id80530">8.1 File Inclusion</a></h3> <p>A file can be included in the following way:</p> <div class="example"><pre> -include(File). -include_lib(File).</pre></div> <p><span class="code">File</span>, 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 <span class="code">.hrl</span> be used for include files.</p> <p><span class="code">File</span> may start with a path component <span class="code">$VAR</span>, for some string <span class="code">VAR</span>. If that is the case, the value of the environment variable <span class="code">VAR</span> as returned by <span class="code">os:getenv(VAR)</span> is substituted for <span class="code">$VAR</span>. If <span class="code">os:getenv(VAR)</span> returns <span class="code">false</span>, <span class="code">$VAR</span> is left as is.</p> <p>If the filename <span class="code">File</span> 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 <span class="code">include</span> option, in that order. See <span class="code">erlc(1)</span> and <span class="code">compile(3)</span> for details.</p> <p>Examples:</p> <div class="example"><pre> -include("my_records.hrl"). -include("incdir/my_records.hrl"). -include("/home/user/proj/my_records.hrl"). -include("$PROJ_ROOT/my_records.hrl").</pre></div> <p><span class="code">include_lib</span> is similar to <span class="code">include</span>, 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> <div class="example"><pre> -include_lib("kernel/include/file.hrl").</pre></div> <p>The code server uses <span class="code">code:lib_dir(kernel)</span> to find the directory of the current (latest) version of Kernel, and then the subdirectory <span class="code">include</span> is searched for the file <span class="code">file.hrl</span>.</p> <h3><a name="id80659">8.2 Defining and Using Macros</a></h3> <p>A macro is defined the following way:</p> <div class="example"><pre> -define(Const, Replacement). -define(Func(Var1,...,VarN), Replacement).</pre></div> <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> <div class="example"><pre> ?Const ?Func(Arg1,...,ArgN)</pre></div> <p>Macros are expanded during compilation. A simple macro <span class="code">?Const</span> will be replaced with <span class="code">Replacement</span>. Example:</p> <div class="example"><pre> -define(TIMEOUT, 200). ... call(Request) -> server:call(refserver, Request, ?TIMEOUT).</pre></div> <p>This will be expanded to:</p> <div class="example"><pre> call(Request) -> server:call(refserver, Request, 200).</pre></div> <p>A macro <span class="code">?Func(Arg1,...,ArgN)</span> will be replaced with <span class="code">Replacement</span>, where all occurrences of a variable <span class="code">Var</span> from the macro definition are replaced with the corresponding argument <span class="code">Arg</span>. Example:</p> <div class="example"><pre> -define(MACRO1(X, Y), {a, X, b, Y}). ... bar(X) -> ?MACRO1(a, b), ?MACRO1(X, 123)</pre></div> <p>This will be expanded to:</p> <div class="example"><pre> bar(X) -> {a,a,b,b}, {a,X,b,123}.</pre></div> <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 <span class="code">'P'</span> option. <span class="code">compile:file(File, ['P'])</span>. This produces a listing of the parsed code after preprocessing and parse transforms, in the file <span class="code">File.P</span>.</p> <h3><a name="id80782">8.3 Predefined Macros</a></h3> <p>The following macros are predefined:</p> <dl> <dt><strong><span class="code">?MODULE</span></strong></dt> <dd>The name of the current module.</dd> <dt><strong><span class="code">?MODULE_STRING</span>.</strong></dt> <dd>The name of the current module, as a string.</dd> <dt><strong><span class="code">?FILE</span>.</strong></dt> <dd>The file name of the current module.</dd> <dt><strong><span class="code">?LINE</span>.</strong></dt> <dd>The current line number.</dd> <dt><strong><span class="code">?MACHINE</span>.</strong></dt> <dd>The machine name, <span class="code">'BEAM'</span>.</dd> </dl> <h3><a name="id80850">8.4 Macros Overloading</a></h3> <p>It is possible to overload macros, except for predefined macros. An overloaded macro has more than one definition, each with a different number of arguments.</p> <p>The feature was added in Erlang 5.7.5/OTP R13B04.</p> <p>A macro <span class="code">?Func(Arg1,...,ArgN)</span> with a (possibly empty) list of arguments results in an error message if there is at least one definition of <span class="code">Func</span> with arguments, but none with N arguments.</p> <p>Assuming these definitions:</p> <div class="example"><pre> -define(F0(), c). -define(F1(A), A). -define(C, m:f).</pre></div> <p>the following will not work:</p> <div class="example"><pre> f0() -> ?F0. % No, an empty list of arguments expected. f1(A) -> ?F1(A, A). % No, exactly one argument expected.</pre></div> <p>On the other hand,</p> <div class="example"><pre> f() -> ?C().</pre></div> <p>will expand to</p> <div class="example"><pre> f() -> m:f().</pre></div> <h3><a name="id80919">8.5 Flow Control in Macros</a></h3> <p>The following macro directives are supplied:</p> <dl> <dt><strong><span class="code">-undef(Macro).</span></strong></dt> <dd>Causes the macro to behave as if it had never been defined.</dd> <dt><strong><span class="code">-ifdef(Macro).</span></strong></dt> <dd>Evaluate the following lines only if <span class="code">Macro</span> is defined.</dd> <dt><strong><span class="code">-ifndef(Macro).</span></strong></dt> <dd>Evaluate the following lines only if <span class="code">Macro</span> is not defined.</dd> <dt><strong><span class="code">-else.</span></strong></dt> <dd>Only allowed after an <span class="code">ifdef</span> or <span class="code">ifndef</span> directive. If that condition was false, the lines following <span class="code">else</span> are evaluated instead.</dd> <dt><strong><span class="code">-endif.</span></strong></dt> <dd>Specifies the end of an <span class="code">ifdef</span> or <span class="code">ifndef</span> directive.</dd> </dl> <div class="note"> <div class="label">Note</div> <div class="content"><p> <p>The macro directives cannot be used inside functions.</p> </p></div> </div> <p>Example:</p> <div class="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></div> <p>When trace output is desired, <span class="code">debug</span> should be defined when the module <span class="code">m</span> is compiled:</p> <div class="example"><pre> % <span class="bold_code">erlc -Ddebug m.erl</span> or 1> <span class="bold_code">c(m, {d, debug}).</span> {ok,m}</pre></div> <p><span class="code">?LOG(Arg)</span> will then expand to a call to <span class="code">io:format/2</span> and provide the user with some simple trace output.</p> <h3><a name="id81056">8.6 Stringifying Macro Arguments</a></h3> <p>The construction <span class="code">??Arg</span>, where <span class="code">Arg</span> is a macro argument, will be expanded to a string containing the tokens of the argument. This is similar to the <span class="code">#arg</span> stringifying construction in C.</p> <p>The feature was added in Erlang 5.0/OTP R7.</p> <p>Example:</p> <div class="example"><pre> -define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])). ?TESTCALL(myfunction(1,2)), ?TESTCALL(you:function(2,1)).</pre></div> <p>results in</p> <div class="example"><pre> io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",myfunction(1,2)]), io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).</pre></div> <p>That is, a trace output with both the function called and the resulting value.</p> </div> <div class="footer"> <hr> <p>Copyright © 2003-2012 Ericsson AB. All Rights Reserved.</p> </div> </div> </div></body> </html>