## 4 Macros

Macros in Erlang are written with the following syntax:

    -define(Const, Replacement).
    -define(Fun(Var1, Var2,.., Var), Replacement).

Macros are expanded when the syntax `?MacroName` is encountered.

Consider the macro definition:

    -define(timeout, 200).

The expression `?timeout`, which can occur anywhere in the code which follows the macro definition, will be replaced by `200`.

Macros with arguments are written as follows:

          -define(macro1(X, Y), {a, X, b, Y}).

This type of macro can be used as follows:

    bar(X) ->
        ?macro1(a, b),
        ?macro1(X, 123)

This expands to:

    bar(X) ->
        {a,a,b,b},
        {a,X,b,123}.

### 4.1 Macros and Tokens

Macro expansion works at a token level. We might define a macro as follows:

    -define(macro2(X, Y), {a,X,b,Y).

The replacement value of the macro is not a valid Erlang term because the closing right curly bracket is missing. `macro2` expands into a sequence of tokens `{`, `a`, `X` which are then pasted into the place where the macro is used.

We might use this macro as follows:

    bar() ->
        ?macro2(x,y)}.

This will expand into the valid sequence of tokens `{a,x,y,b}` before being parsed and compiled.

| It is good programming practise to ensure that the replacement text of a macro is a valid Erlang syntactic form.

### 4.2 Pre-Defined Macros

The following macros are pre-defined:

`?MODULE`.
  This macro returns the name of the current module.
`?MODULE_STRING`.
  This macro returns the name of the current module, as a string.
`?FILE`.
  This macro returns the current file name.
`?LINE`.
  This macro returns the current line number.
`?MACHINE`.
  This macro returns the current machine name, `'BEAM'`,

### 4.3 Stringifying Macro Arguments

The construction `??Arg` for an argument to a macro expands to a string containing the tokens of the argument, similar to the `#arg` stringifying construction in C. This was added in Erlang 5.0 (OTP R7A).

Example:

    -define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).

    ?TESTCALL(myfunction(1,2)),
    ?TESTCALL(you:function(2,1)).

results in

    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)]).

### 4.4 Flow Control in Macros

The following macro directives are supplied:

-undef(Macro).
  Causes the macro to behave as if it had never been defined.
-ifdef(Macro).
  Do the following lines if `Macro` is defined.
-ifndef(Macro).
  Do the following lines if `Macro` is not defined.
-else.
  "else" macro
-endif.
  "endif" macro.

The conditional macros must be properly nested. They are usually grouped as follows:

    -ifdef(debug)
    -define(....)
    -else
    -define(...)
    -endif

The following example illustrates this grouping:

    -define(debug, true).
    -ifdef(debug).
    -define(trace(Str, X), io:format("Mod:~w line:~w ~p ~p~n",
                                     [?MODULE,?LINE, Str, X])).
    -else.
    -define(trace(X, Y), true).
    -endif.

Given these definitions, the expression `?trace("X=", X).` in line 10 of the module `foo` expands to:

    io:format("Mod:~w line:~w ~p ~p~n",[foo,100,"X=",[X]]),

If we remove the `-define(debug, true).` line, then the same expression expands to `true`.

### 4.5 A Macro Expansion Utility

The following code can be used to expand a macro and display the result:

    -module(mexpand).
    -export([file/1]).
    -import(lists, [foreach/2]).
    file(File) ->
      case epp:parse_file(File ++ ".erl", [],[]) of
        {ok, L} ->
          {ok, Stream} = file:open(File ++ ".out", write),
          foreach(fun(X) ->
                    io:format(Stream,"~s~n",[erl_pp:form(X)])
                  end, L),
          file:close(Stream)
      end.

Alternatively, we can compile the file with the `'P'` option. `compile:file(File, ['P'])` produces a list file `File.P`, in which the result of any macro expansions can be seen.

Copyright © 1991-2002 Ericsson Utvecklings AB