<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="generator" content="ExDoc v0.19.1"> <title>Macro – Elixir v1.7.2</title> <link rel="stylesheet" href="dist/app-240d7fc7e5.css" /> <link rel="canonical" href="https://hexdocs.pm/elixir/v1.7/Macro.html" /> <script src="dist/sidebar_items-cdf4e58b19.js"></script> </head> <body data-type="modules"> <script>try { if(localStorage.getItem('night-mode')) document.body.className += ' night-mode'; } catch (e) { }</script> <div class="main"> <button class="sidebar-button sidebar-toggle"> <span class="icon-menu" aria-hidden="true"></span> <span class="sr-only">Toggle Sidebar</span> </button> <button class="sidebar-button night-mode-toggle"> <span class="icon-theme" aria-hidden="true"></span> <span class="sr-only">Toggle Theme</span> </button> <section class="sidebar"> <a href="http://elixir-lang.org/docs.html" class="sidebar-projectLink"> <div class="sidebar-projectDetails"> <h1 class="sidebar-projectName"> Elixir </h1> <h2 class="sidebar-projectVersion"> v1.7.2 </h2> </div> <img src="assets/logo.png" alt="Elixir" class="sidebar-projectImage"> </a> <form class="sidebar-search" action="search.html"> <button type="submit" class="search-button"> <span class="icon-search" aria-hidden="true"></span> </button> <input name="q" type="text" id="search-list" class="search-input" placeholder="Search" aria-label="Search" autocomplete="off" /> </form> <ul class="sidebar-listNav"> <li><a id="extras-list" href="#full-list">Pages</a></li> <li><a id="modules-list" href="#full-list">Modules</a></li> <li><a id="exceptions-list" href="#full-list">Exceptions</a></li> </ul> <div class="gradient"></div> <ul id="full-list" class="sidebar-fullList"></ul> </section> <section class="content"> <div class="content-outer"> <div id="content" class="content-inner"> <h1> <small class="visible-xs">Elixir v1.7.2</small> Macro <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L3" title="View Source" class="view-source" rel="help"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </h1> <section id="moduledoc"> <p>Conveniences for working with macros.</p> <h2 id="module-custom-sigils" class="section-heading"> <a href="#module-custom-sigils" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Custom Sigils </h2> <p>To create a custom sigil, define a function with the name <code class="inline">sigil_{identifier}</code> that takes two arguments. The first argument will be the string, the second will be a charlist containing any modifiers. If the sigil is lower case (such as <code class="inline">sigil_x</code>) then the string argument will allow interpolation. If the sigil is upper case (such as <code class="inline">sigil_X</code>) then the string will not be interpolated.</p> <p>Valid modifiers include only lower and upper case letters. Other characters will cause a syntax error.</p> <p>The module containing the custom sigil must be imported before the sigil syntax can be used.</p> <h3 id="module-examples" class="section-heading"> <a href="#module-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h3> <pre><code class="nohighlight makeup elixir"><span class="kd">defmodule</span><span class="w"> </span><span class="nc">MySigils</span><span class="w"> </span><span class="k" data-group-id="4084282387-1">do</span><span class="w"> </span><span class="kd">defmacro</span><span class="w"> </span><span class="nf">sigil_x</span><span class="p" data-group-id="4084282387-2">(</span><span class="n">term</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="4084282387-3">[</span><span class="sc">?r</span><span class="p" data-group-id="4084282387-3">]</span><span class="p" data-group-id="4084282387-2">)</span><span class="w"> </span><span class="k" data-group-id="4084282387-4">do</span><span class="w"> </span><span class="k">quote</span><span class="w"> </span><span class="k" data-group-id="4084282387-5">do</span><span class="w"> </span><span class="k">unquote</span><span class="p" data-group-id="4084282387-6">(</span><span class="n">term</span><span class="p" data-group-id="4084282387-6">)</span><span class="w"> </span><span class="o">|></span><span class="w"> </span><span class="nc">String</span><span class="o">.</span><span class="n">reverse</span><span class="p" data-group-id="4084282387-7">(</span><span class="p" data-group-id="4084282387-7">)</span><span class="w"> </span><span class="k" data-group-id="4084282387-5">end</span><span class="w"> </span><span class="k" data-group-id="4084282387-4">end</span><span class="w"> </span><span class="kd">defmacro</span><span class="w"> </span><span class="nf">sigil_x</span><span class="p" data-group-id="4084282387-8">(</span><span class="n">term</span><span class="p">,</span><span class="w"> </span><span class="c">_modifiers</span><span class="p" data-group-id="4084282387-8">)</span><span class="w"> </span><span class="k" data-group-id="4084282387-9">do</span><span class="w"> </span><span class="n">term</span><span class="w"> </span><span class="k" data-group-id="4084282387-9">end</span><span class="w"> </span><span class="kd">defmacro</span><span class="w"> </span><span class="nf">sigil_X</span><span class="p" data-group-id="4084282387-10">(</span><span class="n">term</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="4084282387-11">[</span><span class="sc">?r</span><span class="p" data-group-id="4084282387-11">]</span><span class="p" data-group-id="4084282387-10">)</span><span class="w"> </span><span class="k" data-group-id="4084282387-12">do</span><span class="w"> </span><span class="k">quote</span><span class="w"> </span><span class="k" data-group-id="4084282387-13">do</span><span class="w"> </span><span class="k">unquote</span><span class="p" data-group-id="4084282387-14">(</span><span class="n">term</span><span class="p" data-group-id="4084282387-14">)</span><span class="w"> </span><span class="o">|></span><span class="w"> </span><span class="nc">String</span><span class="o">.</span><span class="n">reverse</span><span class="p" data-group-id="4084282387-15">(</span><span class="p" data-group-id="4084282387-15">)</span><span class="w"> </span><span class="k" data-group-id="4084282387-13">end</span><span class="w"> </span><span class="k" data-group-id="4084282387-12">end</span><span class="w"> </span><span class="kd">defmacro</span><span class="w"> </span><span class="nf">sigil_X</span><span class="p" data-group-id="4084282387-16">(</span><span class="n">term</span><span class="p">,</span><span class="w"> </span><span class="c">_modifiers</span><span class="p" data-group-id="4084282387-16">)</span><span class="w"> </span><span class="k" data-group-id="4084282387-17">do</span><span class="w"> </span><span class="n">term</span><span class="w"> </span><span class="k" data-group-id="4084282387-17">end</span><span class="w"> </span><span class="k" data-group-id="4084282387-1">end</span><span class="w"> </span><span class="kn">import</span><span class="w"> </span><span class="nc">MySigils</span><span class="w"> </span><span class="sx">~x(with </span><span class="si" data-group-id="4084282387-18">#{</span><span class="s">"inter"</span><span class="w"> </span><span class="o"><></span><span class="w"> </span><span class="s">"polation"</span><span class="si" data-group-id="4084282387-18">}</span><span class="sx">)</span><span class="w"> </span><span class="c1">#=>"with interpolation"</span><span class="w"> </span><span class="sx">~x(with </span><span class="si" data-group-id="4084282387-19">#{</span><span class="s">"inter"</span><span class="w"> </span><span class="o"><></span><span class="w"> </span><span class="s">"polation"</span><span class="si" data-group-id="4084282387-19">}</span><span class="sx">)r</span><span class="w"> </span><span class="c1">#=>"noitalopretni htiw"</span><span class="w"> </span><span class="sx">~X(without </span><span class="si" data-group-id="4084282387-20">#{</span><span class="s">"interpolation"</span><span class="si" data-group-id="4084282387-20">}</span><span class="sx">)</span><span class="w"> </span><span class="c1">#=>"without \#{"interpolation"}"</span><span class="w"> </span><span class="sx">~X(without </span><span class="si" data-group-id="4084282387-21">#{</span><span class="s">"interpolation"</span><span class="si" data-group-id="4084282387-21">}</span><span class="sx">)r</span><span class="w"> </span><span class="c1">#=>"}\"noitalopretni\"{# tuohtiw"</span></code></pre> </section> <section id="summary" class="details-list"> <h1 class="section-heading"> <a class="hover-link" href="#summary"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this section</span> </a> Summary </h1> <div class="summary-types summary"> <h2> <a href="#types">Types</a> </h2> <div class="summary-row"> <div class="summary-signature"> <a href="#t:expr/0">expr()</a> </div> <div class="summary-synopsis"><p>Represents expressions in the AST</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#t:literal/0">literal()</a> </div> <div class="summary-synopsis"><p>Represents literals in the AST</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#t:t/0">t()</a> </div> <div class="summary-synopsis"><p>Abstract Syntax Tree (AST)</p> </div> </div> </div> <div class="summary-functions summary"> <h2> <a href="#functions">Functions</a> </h2> <div class="summary-row"> <div class="summary-signature"> <a href="#camelize/1">camelize(string)</a> </div> <div class="summary-synopsis"><p>Converts the given string to CamelCase format</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#decompose_call/1">decompose_call(ast)</a> </div> <div class="summary-synopsis"><p>Decomposes a local or remote call into its remote part (when provided), function name and argument list</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#escape/2">escape(expr, opts \\ [])</a> </div> <div class="summary-synopsis"><p>Recursively escapes a value so it can be inserted into a syntax tree</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#expand/2">expand(tree, env)</a> </div> <div class="summary-synopsis"><p>Receives an AST node and expands it until it can no longer be expanded</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#expand_once/2">expand_once(ast, env)</a> </div> <div class="summary-synopsis"><p>Receives an AST node and expands it once</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#generate_arguments/2">generate_arguments(amount, context)</a> </div> <div class="summary-synopsis"><p>Generates AST nodes for a given number of required argument variables using <a href="Macro.html#var/2"><code class="inline">Macro.var/2</code></a></p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#operator?/2">operator?(name, arity)</a> </div> <div class="summary-synopsis"><p>Returns <code class="inline">true</code> if the given name and arity is an operator</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#pipe/3">pipe(expr, call_args, position)</a> </div> <div class="summary-synopsis"><p>Pipes <code class="inline">expr</code> into the <code class="inline">call_args</code> at the given <code class="inline">position</code></p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#postwalk/2">postwalk(ast, fun)</a> </div> <div class="summary-synopsis"><p>Performs a depth-first, post-order traversal of quoted expressions</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#postwalk/3">postwalk(ast, acc, fun)</a> </div> <div class="summary-synopsis"><p>Performs a depth-first, post-order traversal of quoted expressions using an accumulator</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#prewalk/2">prewalk(ast, fun)</a> </div> <div class="summary-synopsis"><p>Performs a depth-first, pre-order traversal of quoted expressions</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#prewalk/3">prewalk(ast, acc, fun)</a> </div> <div class="summary-synopsis"><p>Performs a depth-first, pre-order traversal of quoted expressions using an accumulator</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#quoted_literal?/1">quoted_literal?(term)</a> </div> <div class="summary-synopsis"><p>Returns <code class="inline">true</code> if the given quoted expression is an AST literal</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#special_form?/2">special_form?(name, arity)</a> </div> <div class="summary-synopsis"><p>Returns <code class="inline">true</code> if the given name and arity is a special form</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#to_string/2">to_string(tree, fun \\ fn _ast, string -> string end)</a> </div> <div class="summary-synopsis"><p>Converts the given expression AST to a string</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#traverse/4">traverse(ast, acc, pre, post)</a> </div> <div class="summary-synopsis"><p>Performs a depth-first traversal of quoted expressions using an accumulator</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#underscore/1">underscore(atom)</a> </div> <div class="summary-synopsis"><p>Converts the given atom or binary to underscore format</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#unescape_string/1">unescape_string(chars)</a> </div> <div class="summary-synopsis"><p>Unescapes the given chars</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#unescape_string/2">unescape_string(chars, map)</a> </div> <div class="summary-synopsis"><p>Unescapes the given chars according to the map given</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#unpipe/1">unpipe(expr)</a> </div> <div class="summary-synopsis"><p>Breaks a pipeline expression into a list</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#update_meta/2">update_meta(quoted, fun)</a> </div> <div class="summary-synopsis"><p>Applies the given function to the node metadata if it contains one</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#validate/1">validate(expr)</a> </div> <div class="summary-synopsis"><p>Validates the given expressions are valid quoted expressions</p> </div> </div> <div class="summary-row"> <div class="summary-signature"> <a href="#var/2">var(var, context)</a> </div> <div class="summary-synopsis"><p>Generates an AST node representing the variable given by the atoms <code class="inline">var</code> and <code class="inline">context</code></p> </div> </div> </div> </section> <section id="types" class="details-list"> <h1 class="section-heading"> <a class="hover-link" href="#types"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this section</span> </a> Types </h1> <div class="types-list"> <div class="detail" id="t:expr/0"> <div class="detail-header"> <a href="#t:expr/0" class="detail-link" title="Link to this type"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this type</span> </a> <span class="signature">expr()</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L65" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>expr() :: {<a href="#t:expr/0">expr</a>() | <a href="typespecs.html#basic-types">atom</a>(), <a href="typespecs.html#built-in-types">keyword</a>(), <a href="typespecs.html#basic-types">atom</a>() | [<a href="#t:t/0">t</a>()]}</pre> </div> </div> <section class="docstring"> <p>Represents expressions in the AST</p> </section> </div> <div class="detail" id="t:literal/0"> <div class="detail-header"> <a href="#t:literal/0" class="detail-link" title="Link to this type"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this type</span> </a> <span class="signature">literal()</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L68" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>literal() :: <a href="typespecs.html#basic-types">atom</a>() | <a href="typespecs.html#built-in-types">number</a>() | <a href="typespecs.html#built-in-types">binary</a>() | (... -> <a href="typespecs.html#basic-types">any</a>()) | {<a href="#t:t/0">t</a>(), <a href="#t:t/0">t</a>()} | [<a href="#t:t/0">t</a>()]</pre> </div> </div> <section class="docstring"> <p>Represents literals in the AST</p> </section> </div> <div class="detail" id="t:t/0"> <div class="detail-header"> <a href="#t:t/0" class="detail-link" title="Link to this type"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this type</span> </a> <span class="signature">t()</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L62" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>t() :: <a href="#t:expr/0">expr</a>() | <a href="#t:literal/0">literal</a>()</pre> </div> </div> <section class="docstring"> <p>Abstract Syntax Tree (AST)</p> </section> </div> </div> </section> <section id="functions" class="details-list"> <h1 class="section-heading"> <a class="hover-link" href="#functions"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this section</span> </a> Functions </h1> <div class="detail" id="camelize/1"> <div class="detail-header"> <a href="#camelize/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">camelize(string)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L1441" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>camelize(<a href="String.html#t:t/0">String.t</a>()) :: <a href="String.html#t:t/0">String.t</a>()</pre> </div> </div> <section class="docstring"> <p>Converts the given string to CamelCase format.</p> <p>This function was designed to camelize language identifiers/tokens, that’s why it belongs to the <a href="Macro.html#content"><code class="inline">Macro</code></a> module. Do not use it as a general mechanism for camelizing strings as it does not support Unicode or characters that are not valid in Elixir identifiers.</p> <h2 id="camelize/1-examples" class="section-heading"> <a href="#camelize/1-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">camelize</span><span class="p" data-group-id="9670544486-1">(</span><span class="s">"foo_bar"</span><span class="p" data-group-id="9670544486-1">)</span><span class="w"> </span><span class="s">"FooBar"</span></code></pre> <p>If uppercase characters are present, they are not modified in any way as a mechanism to preserve acronyms:</p> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">camelize</span><span class="p" data-group-id="1418066148-1">(</span><span class="s">"API.V1"</span><span class="p" data-group-id="1418066148-1">)</span><span class="w"> </span><span class="s">"API.V1"</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">camelize</span><span class="p" data-group-id="1418066148-2">(</span><span class="s">"API_SPEC"</span><span class="p" data-group-id="1418066148-2">)</span><span class="w"> </span><span class="s">"API_SPEC"</span></code></pre> </section> </div> <div class="detail" id="decompose_call/1"> <div class="detail-header"> <a href="#decompose_call/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">decompose_call(ast)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L356" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>decompose_call(<a href="Macro.html#t:t/0">Macro.t</a>()) :: {<a href="typespecs.html#basic-types">atom</a>(), [<a href="Macro.html#t:t/0">Macro.t</a>()]} | {<a href="Macro.html#t:t/0">Macro.t</a>(), <a href="typespecs.html#basic-types">atom</a>(), [<a href="Macro.html#t:t/0">Macro.t</a>()]} | :error</pre> </div> </div> <section class="docstring"> <p>Decomposes a local or remote call into its remote part (when provided), function name and argument list.</p> <p>Returns <code class="inline">:error</code> when an invalid call syntax is provided.</p> <h2 id="decompose_call/1-examples" class="section-heading"> <a href="#decompose_call/1-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">decompose_call</span><span class="p" data-group-id="1226024700-1">(</span><span class="k">quote</span><span class="p" data-group-id="1226024700-2">(</span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">foo</span><span class="p" data-group-id="1226024700-2">)</span><span class="p" data-group-id="1226024700-1">)</span><span class="w"> </span><span class="p" data-group-id="1226024700-3">{</span><span class="ss">:foo</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="1226024700-4">[</span><span class="p" data-group-id="1226024700-4">]</span><span class="p" data-group-id="1226024700-3">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">decompose_call</span><span class="p" data-group-id="1226024700-5">(</span><span class="k">quote</span><span class="p" data-group-id="1226024700-6">(</span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">foo</span><span class="p" data-group-id="1226024700-7">(</span><span class="p" data-group-id="1226024700-7">)</span><span class="p" data-group-id="1226024700-6">)</span><span class="p" data-group-id="1226024700-5">)</span><span class="w"> </span><span class="p" data-group-id="1226024700-8">{</span><span class="ss">:foo</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="1226024700-9">[</span><span class="p" data-group-id="1226024700-9">]</span><span class="p" data-group-id="1226024700-8">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">decompose_call</span><span class="p" data-group-id="1226024700-10">(</span><span class="k">quote</span><span class="p" data-group-id="1226024700-11">(</span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">foo</span><span class="p" data-group-id="1226024700-12">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p" data-group-id="1226024700-12">)</span><span class="p" data-group-id="1226024700-11">)</span><span class="p" data-group-id="1226024700-10">)</span><span class="w"> </span><span class="p" data-group-id="1226024700-13">{</span><span class="ss">:foo</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="1226024700-14">[</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p" data-group-id="1226024700-14">]</span><span class="p" data-group-id="1226024700-13">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">decompose_call</span><span class="p" data-group-id="1226024700-15">(</span><span class="k">quote</span><span class="p" data-group-id="1226024700-16">(</span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="nc">Elixir.M</span><span class="o">.</span><span class="n">foo</span><span class="p" data-group-id="1226024700-17">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p" data-group-id="1226024700-17">)</span><span class="p" data-group-id="1226024700-16">)</span><span class="p" data-group-id="1226024700-15">)</span><span class="w"> </span><span class="p" data-group-id="1226024700-18">{</span><span class="p" data-group-id="1226024700-19">{</span><span class="ss">:__aliases__</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="1226024700-20">[</span><span class="p" data-group-id="1226024700-20">]</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="1226024700-21">[</span><span class="ss">:Elixir</span><span class="p">,</span><span class="w"> </span><span class="ss">:M</span><span class="p" data-group-id="1226024700-21">]</span><span class="p" data-group-id="1226024700-19">}</span><span class="p">,</span><span class="w"> </span><span class="ss">:foo</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="1226024700-22">[</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p" data-group-id="1226024700-22">]</span><span class="p" data-group-id="1226024700-18">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">decompose_call</span><span class="p" data-group-id="1226024700-23">(</span><span class="k">quote</span><span class="p" data-group-id="1226024700-24">(</span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="mi">42</span><span class="p" data-group-id="1226024700-24">)</span><span class="p" data-group-id="1226024700-23">)</span><span class="w"> </span><span class="ss">:error</span></code></pre> </section> </div> <div class="detail" id="escape/2"> <span id="escape/1"></span> <div class="detail-header"> <a href="#escape/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">escape(expr, opts \\ [])</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L419" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>escape(<a href="typespecs.html#built-in-types">term</a>(), <a href="typespecs.html#built-in-types">keyword</a>()) :: <a href="Macro.html#t:t/0">Macro.t</a>()</pre> </div> </div> <section class="docstring"> <p>Recursively escapes a value so it can be inserted into a syntax tree.</p> <h2 id="escape/2-examples" class="section-heading"> <a href="#escape/2-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">escape</span><span class="p" data-group-id="3612874761-1">(</span><span class="ss">:foo</span><span class="p" data-group-id="3612874761-1">)</span><span class="w"> </span><span class="ss">:foo</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">escape</span><span class="p" data-group-id="3612874761-2">(</span><span class="p" data-group-id="3612874761-3">{</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="3612874761-3">}</span><span class="p" data-group-id="3612874761-2">)</span><span class="w"> </span><span class="p" data-group-id="3612874761-4">{</span><span class="ss">:{}</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="3612874761-5">[</span><span class="p" data-group-id="3612874761-5">]</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="3612874761-6">[</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="3612874761-6">]</span><span class="p" data-group-id="3612874761-4">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">escape</span><span class="p" data-group-id="3612874761-7">(</span><span class="p" data-group-id="3612874761-8">{</span><span class="ss">:unquote</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="3612874761-9">[</span><span class="p" data-group-id="3612874761-9">]</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="3612874761-10">[</span><span class="mi">1</span><span class="p" data-group-id="3612874761-10">]</span><span class="p" data-group-id="3612874761-8">}</span><span class="p">,</span><span class="w"> </span><span class="ss">unquote</span><span class="p">:</span><span class="w"> </span><span class="no">true</span><span class="p" data-group-id="3612874761-7">)</span><span class="w"> </span><span class="mi">1</span></code></pre> <h2 id="escape/2-options" class="section-heading"> <a href="#escape/2-options" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Options </h2> <ul> <li><p><code class="inline">:unquote</code> - when true, this function leaves <a href="Kernel.SpecialForms.html#unquote/1"><code class="inline">unquote/1</code></a> and <a href="Kernel.SpecialForms.html#unquote_splicing/1"><code class="inline">unquote_splicing/1</code></a> statements unescaped, effectively unquoting the contents on escape. This option is useful only when escaping ASTs which may have quoted fragments in them. Defaults to false.</p> </li> <li><p><code class="inline">:prune_metadata</code> - when true, removes metadata from escaped AST nodes. Note this option changes the semantics of escaped code and it should only be used when escaping ASTs, never values. Defaults to false.</p> <p>As an example, <code class="inline">ExUnit</code> stores the AST of every assertion, so when an assertion fails we can show code snippets to users. Without this option, each time the test module is compiled, we get a different MD5 of the module byte code, because the AST contains metadata, such as counters, specific to the compilation environment. By pruning the metadata, we ensure that the module is deterministic and reduce the amount of data <code class="inline">ExUnit</code> needs to keep around.</p> </li> </ul> <h2 id="escape/2-comparison-to-kernel-quote-2" class="section-heading"> <a href="#escape/2-comparison-to-kernel-quote-2" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Comparison to <a href="https://hexdocs.pm/elixir/Kernel.html#quote/2"><code class="inline">Kernel.quote/2</code></a> </h2> <p>The <a href="#escape/2"><code class="inline">escape/2</code></a> function is sometimes confused with <a href="Kernel.SpecialForms.html#quote/2"><code class="inline">Kernel.SpecialForms.quote/2</code></a>, because the above examples behave the same with both. The key difference is best illustrated when the value to escape is stored in a variable.</p> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">escape</span><span class="p" data-group-id="8050886152-1">(</span><span class="p" data-group-id="8050886152-2">{</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="8050886152-2">}</span><span class="p" data-group-id="8050886152-1">)</span><span class="w"> </span><span class="p" data-group-id="8050886152-3">{</span><span class="ss">:{}</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="8050886152-4">[</span><span class="p" data-group-id="8050886152-4">]</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="8050886152-5">[</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="8050886152-5">]</span><span class="p" data-group-id="8050886152-3">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="k">quote</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="8050886152-6">{</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="8050886152-6">}</span><span class="w"> </span><span class="p" data-group-id="8050886152-7">{</span><span class="ss">:{}</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="8050886152-8">[</span><span class="p" data-group-id="8050886152-8">]</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="8050886152-9">[</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="8050886152-9">]</span><span class="p" data-group-id="8050886152-7">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="n">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p" data-group-id="8050886152-10">{</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="8050886152-10">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">escape</span><span class="p" data-group-id="8050886152-11">(</span><span class="n">value</span><span class="p" data-group-id="8050886152-11">)</span><span class="w"> </span><span class="p" data-group-id="8050886152-12">{</span><span class="ss">:{}</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="8050886152-13">[</span><span class="p" data-group-id="8050886152-13">]</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="8050886152-14">[</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="8050886152-14">]</span><span class="p" data-group-id="8050886152-12">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="k">quote</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="p" data-group-id="8050886152-15">{</span><span class="ss">:value</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="8050886152-16">[</span><span class="p" data-group-id="8050886152-16">]</span><span class="p">,</span><span class="w"> </span><span class="bp">__MODULE__</span><span class="p" data-group-id="8050886152-15">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="n">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p" data-group-id="8050886152-17">{</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="8050886152-17">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="k">quote</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="k">unquote</span><span class="p" data-group-id="8050886152-18">(</span><span class="n">value</span><span class="p" data-group-id="8050886152-18">)</span><span class="w"> </span><span class="p" data-group-id="8050886152-19">{</span><span class="ss">:a</span><span class="p">,</span><span class="w"> </span><span class="ss">:b</span><span class="p">,</span><span class="w"> </span><span class="ss">:c</span><span class="p" data-group-id="8050886152-19">}</span></code></pre> <p><a href="#escape/2"><code class="inline">escape/2</code></a> is used to escape <em>values</em> (either directly passed or variable bound), while <a href="Kernel.SpecialForms.html#quote/2"><code class="inline">Kernel.SpecialForms.quote/2</code></a> produces syntax trees for expressions.</p> </section> </div> <div class="detail" id="expand/2"> <div class="detail-header"> <a href="#expand/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">expand(tree, env)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L1332" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </div> <section class="docstring"> <p>Receives an AST node and expands it until it can no longer be expanded.</p> <p>This function uses <a href="#expand_once/2"><code class="inline">expand_once/2</code></a> under the hood. Check it out for more information and examples.</p> </section> </div> <div class="detail" id="expand_once/2"> <div class="detail-header"> <a href="#expand_once/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">expand_once(ast, env)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L1179" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </div> <section class="docstring"> <p>Receives an AST node and expands it once.</p> <p>The following contents are expanded:</p> <ul> <li>Macros (local or remote) </li> <li>Aliases are expanded (if possible) and return atoms </li> <li>Compilation environment macros (<a href="Kernel.SpecialForms.html#__CALLER__/0"><code class="inline">__CALLER__/0</code></a>, <a href="Kernel.SpecialForms.html#__DIR__/0"><code class="inline">__DIR__/0</code></a>, <a href="Kernel.SpecialForms.html#__ENV__/0"><code class="inline">__ENV__/0</code></a> and <a href="Kernel.SpecialForms.html#__MODULE__/0"><code class="inline">__MODULE__/0</code></a>) </li> <li>Module attributes reader (<code class="inline">@foo</code>) </li> </ul> <p>If the expression cannot be expanded, it returns the expression itself. Notice that <a href="#expand_once/2"><code class="inline">expand_once/2</code></a> performs the expansion just once and it is not recursive. Check <a href="#expand/2"><code class="inline">expand/2</code></a> for expansion until the node can no longer be expanded.</p> <h2 id="expand_once/2-examples" class="section-heading"> <a href="#expand_once/2-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <p>In the example below, we have a macro that generates a module with a function named <code class="inline">name_length</code> that returns the length of the module name. The value of this function will be calculated at compilation time and not at runtime.</p> <p>Consider the implementation below:</p> <pre><code class="nohighlight makeup elixir"><span class="kd">defmacro</span><span class="w"> </span><span class="nf">defmodule_with_length</span><span class="p" data-group-id="9385563706-1">(</span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">block</span><span class="p" data-group-id="9385563706-1">)</span><span class="w"> </span><span class="k" data-group-id="9385563706-2">do</span><span class="w"> </span><span class="n">length</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">length</span><span class="p" data-group-id="9385563706-3">(</span><span class="nc">Atom</span><span class="o">.</span><span class="n">to_charlist</span><span class="p" data-group-id="9385563706-4">(</span><span class="n">name</span><span class="p" data-group-id="9385563706-4">)</span><span class="p" data-group-id="9385563706-3">)</span><span class="w"> </span><span class="k">quote</span><span class="w"> </span><span class="k" data-group-id="9385563706-5">do</span><span class="w"> </span><span class="kd">defmodule</span><span class="w"> </span><span class="k">unquote</span><span class="p" data-group-id="9385563706-6">(</span><span class="n">name</span><span class="p" data-group-id="9385563706-6">)</span><span class="w"> </span><span class="k" data-group-id="9385563706-7">do</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">name_length</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="k">unquote</span><span class="p" data-group-id="9385563706-8">(</span><span class="n">length</span><span class="p" data-group-id="9385563706-8">)</span><span class="w"> </span><span class="k">unquote</span><span class="p" data-group-id="9385563706-9">(</span><span class="n">block</span><span class="p" data-group-id="9385563706-9">)</span><span class="w"> </span><span class="k" data-group-id="9385563706-7">end</span><span class="w"> </span><span class="k" data-group-id="9385563706-5">end</span><span class="w"> </span><span class="k" data-group-id="9385563706-2">end</span></code></pre> <p>When invoked like this:</p> <pre><code class="nohighlight makeup elixir"><span class="n">defmodule_with_length</span><span class="w"> </span><span class="nc">My.Module</span><span class="w"> </span><span class="k" data-group-id="8449284518-1">do</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">other_function</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">...</span><span class="w"> </span><span class="k" data-group-id="8449284518-1">end</span></code></pre> <p>The compilation will fail because <code class="inline">My.Module</code> when quoted is not an atom, but a syntax tree as follows:</p> <pre><code class="nohighlight makeup elixir"><span class="p" data-group-id="4784994688-1">{</span><span class="ss">:__aliases__</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="4784994688-2">[</span><span class="p" data-group-id="4784994688-2">]</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="4784994688-3">[</span><span class="ss">:My</span><span class="p">,</span><span class="w"> </span><span class="ss">:Module</span><span class="p" data-group-id="4784994688-3">]</span><span class="p" data-group-id="4784994688-1">}</span></code></pre> <p>That said, we need to expand the aliases node above to an atom, so we can retrieve its length. Expanding the node is not straightforward because we also need to expand the caller aliases. For example:</p> <pre><code class="nohighlight makeup elixir"><span class="kn">alias</span><span class="w"> </span><span class="nc">MyHelpers</span><span class="p">,</span><span class="w"> </span><span class="ss">as</span><span class="p">:</span><span class="w"> </span><span class="nc">My</span><span class="w"> </span><span class="n">defmodule_with_length</span><span class="w"> </span><span class="nc">My.Module</span><span class="w"> </span><span class="k" data-group-id="5642156308-1">do</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">other_function</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">...</span><span class="w"> </span><span class="k" data-group-id="5642156308-1">end</span></code></pre> <p>The final module name will be <code class="inline">MyHelpers.Module</code> and not <code class="inline">My.Module</code>. With <a href="Macro.html#expand/2"><code class="inline">Macro.expand/2</code></a>, such aliases are taken into consideration. Local and remote macros are also expanded. We could rewrite our macro above to use this function as:</p> <pre><code class="nohighlight makeup elixir"><span class="kd">defmacro</span><span class="w"> </span><span class="nf">defmodule_with_length</span><span class="p" data-group-id="9222715489-1">(</span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">block</span><span class="p" data-group-id="9222715489-1">)</span><span class="w"> </span><span class="k" data-group-id="9222715489-2">do</span><span class="w"> </span><span class="n">expanded</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">expand</span><span class="p" data-group-id="9222715489-3">(</span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="bp">__CALLER__</span><span class="p" data-group-id="9222715489-3">)</span><span class="w"> </span><span class="n">length</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">length</span><span class="p" data-group-id="9222715489-4">(</span><span class="nc">Atom</span><span class="o">.</span><span class="n">to_charlist</span><span class="p" data-group-id="9222715489-5">(</span><span class="n">expanded</span><span class="p" data-group-id="9222715489-5">)</span><span class="p" data-group-id="9222715489-4">)</span><span class="w"> </span><span class="k">quote</span><span class="w"> </span><span class="k" data-group-id="9222715489-6">do</span><span class="w"> </span><span class="kd">defmodule</span><span class="w"> </span><span class="k">unquote</span><span class="p" data-group-id="9222715489-7">(</span><span class="n">name</span><span class="p" data-group-id="9222715489-7">)</span><span class="w"> </span><span class="k" data-group-id="9222715489-8">do</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">name_length</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="k">unquote</span><span class="p" data-group-id="9222715489-9">(</span><span class="n">length</span><span class="p" data-group-id="9222715489-9">)</span><span class="w"> </span><span class="k">unquote</span><span class="p" data-group-id="9222715489-10">(</span><span class="n">block</span><span class="p" data-group-id="9222715489-10">)</span><span class="w"> </span><span class="k" data-group-id="9222715489-8">end</span><span class="w"> </span><span class="k" data-group-id="9222715489-6">end</span><span class="w"> </span><span class="k" data-group-id="9222715489-2">end</span></code></pre> </section> </div> <div class="detail" id="generate_arguments/2"> <div class="detail-header"> <a href="#generate_arguments/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">generate_arguments(amount, context)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L207" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <span class="note">(since 1.5.0)</span> </div> <section class="docstring"> <p>Generates AST nodes for a given number of required argument variables using <a href="Macro.html#var/2"><code class="inline">Macro.var/2</code></a>.</p> <h2 id="generate_arguments/2-examples" class="section-heading"> <a href="#generate_arguments/2-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">generate_arguments</span><span class="p" data-group-id="4084226385-1">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="bp">__MODULE__</span><span class="p" data-group-id="4084226385-1">)</span><span class="w"> </span><span class="p" data-group-id="4084226385-2">[</span><span class="p" data-group-id="4084226385-3">{</span><span class="ss">:var1</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="4084226385-4">[</span><span class="p" data-group-id="4084226385-4">]</span><span class="p">,</span><span class="w"> </span><span class="bp">__MODULE__</span><span class="p" data-group-id="4084226385-3">}</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="4084226385-5">{</span><span class="ss">:var2</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="4084226385-6">[</span><span class="p" data-group-id="4084226385-6">]</span><span class="p">,</span><span class="w"> </span><span class="bp">__MODULE__</span><span class="p" data-group-id="4084226385-5">}</span><span class="p" data-group-id="4084226385-2">]</span></code></pre> </section> </div> <div class="detail" id="operator?/2"> <div class="detail-header"> <a href="#operator?/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">operator?(name, arity)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L1308" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <span class="note">(since 1.7.0)</span> <div class="specs"> <pre>operator?(name :: <a href="typespecs.html#basic-types">atom</a>(), <a href="typespecs.html#built-in-types">arity</a>()) :: <a href="typespecs.html#built-in-types">boolean</a>()</pre> </div> </div> <section class="docstring"> <p>Returns <code class="inline">true</code> if the given name and arity is an operator.</p> </section> </div> <div class="detail" id="pipe/3"> <div class="detail-header"> <a href="#pipe/3" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">pipe(expr, call_args, position)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L159" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>pipe(<a href="Macro.html#t:t/0">Macro.t</a>(), <a href="Macro.html#t:t/0">Macro.t</a>(), <a href="typespecs.html#basic-types">integer</a>()) :: <a href="Macro.html#t:t/0">Macro.t</a>() | <a href="typespecs.html#built-in-types">no_return</a>()</pre> </div> </div> <section class="docstring"> <p>Pipes <code class="inline">expr</code> into the <code class="inline">call_args</code> at the given <code class="inline">position</code>.</p> </section> </div> <div class="detail" id="postwalk/2"> <div class="detail-header"> <a href="#postwalk/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">postwalk(ast, fun)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L308" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>postwalk(<a href="#t:t/0">t</a>(), (<a href="#t:t/0">t</a>() -> <a href="#t:t/0">t</a>())) :: <a href="#t:t/0">t</a>()</pre> </div> </div> <section class="docstring"> <p>Performs a depth-first, post-order traversal of quoted expressions.</p> </section> </div> <div class="detail" id="postwalk/3"> <div class="detail-header"> <a href="#postwalk/3" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">postwalk(ast, acc, fun)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L317" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>postwalk(<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>(), (<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>() -> {<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>()})) :: {<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>()}</pre> </div> </div> <section class="docstring"> <p>Performs a depth-first, post-order traversal of quoted expressions using an accumulator.</p> </section> </div> <div class="detail" id="prewalk/2"> <div class="detail-header"> <a href="#prewalk/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">prewalk(ast, fun)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L291" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>prewalk(<a href="#t:t/0">t</a>(), (<a href="#t:t/0">t</a>() -> <a href="#t:t/0">t</a>())) :: <a href="#t:t/0">t</a>()</pre> </div> </div> <section class="docstring"> <p>Performs a depth-first, pre-order traversal of quoted expressions.</p> </section> </div> <div class="detail" id="prewalk/3"> <div class="detail-header"> <a href="#prewalk/3" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">prewalk(ast, acc, fun)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L300" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>prewalk(<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>(), (<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>() -> {<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>()})) :: {<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>()}</pre> </div> </div> <section class="docstring"> <p>Performs a depth-first, pre-order traversal of quoted expressions using an accumulator.</p> </section> </div> <div class="detail" id="quoted_literal?/1"> <div class="detail-header"> <a href="#quoted_literal?/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">quoted_literal?(term)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L1321" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <span class="note">(since 1.7.0)</span> <div class="specs"> <pre>quoted_literal?(<a href="#t:literal/0">literal</a>()) :: true</pre> <pre>quoted_literal?(<a href="#t:expr/0">expr</a>()) :: false</pre> </div> </div> <section class="docstring"> <p>Returns <code class="inline">true</code> if the given quoted expression is an AST literal.</p> </section> </div> <div class="detail" id="special_form?/2"> <div class="detail-header"> <a href="#special_form?/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">special_form?(name, arity)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L1297" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <span class="note">(since 1.7.0)</span> <div class="specs"> <pre>special_form?(name :: <a href="typespecs.html#basic-types">atom</a>(), <a href="typespecs.html#built-in-types">arity</a>()) :: <a href="typespecs.html#built-in-types">boolean</a>()</pre> </div> </div> <section class="docstring"> <p>Returns <code class="inline">true</code> if the given name and arity is a special form.</p> </section> </div> <div class="detail" id="to_string/2"> <span id="to_string/1"></span> <div class="detail-header"> <a href="#to_string/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">to_string(tree, fun \\ fn _ast, string -> string end)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L777" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>to_string(<a href="Macro.html#t:t/0">Macro.t</a>(), (<a href="Macro.html#t:t/0">Macro.t</a>(), <a href="String.html#t:t/0">String.t</a>() -> <a href="String.html#t:t/0">String.t</a>())) :: <a href="String.html#t:t/0">String.t</a>()</pre> </div> </div> <section class="docstring"> <p>Converts the given expression AST to a string.</p> <p>The given <code class="inline">fun</code> is called for every node in the AST with two arguments: the AST of the node being printed and the string representation of that same node. The return value of this function is used as the final string representation for that AST node.</p> <p>This function discards all formatting of the original code.</p> <h2 id="to_string/2-examples" class="section-heading"> <a href="#to_string/2-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">to_string</span><span class="p" data-group-id="7442467463-1">(</span><span class="k">quote</span><span class="p" data-group-id="7442467463-2">(</span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">foo</span><span class="o">.</span><span class="n">bar</span><span class="p" data-group-id="7442467463-3">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p" data-group-id="7442467463-3">)</span><span class="p" data-group-id="7442467463-2">)</span><span class="p" data-group-id="7442467463-1">)</span><span class="w"> </span><span class="s">"foo.bar(1, 2, 3)"</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">to_string</span><span class="p" data-group-id="7442467463-4">(</span><span class="k">quote</span><span class="p" data-group-id="7442467463-5">(</span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="p" data-group-id="7442467463-5">)</span><span class="p">,</span><span class="w"> </span><span class="k" data-group-id="7442467463-6">fn</span><span class="w"> </span><span class="gp unselectable">...> </span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="c">_string</span><span class="w"> </span><span class="o">-></span><span class="w"> </span><span class="s">"one"</span><span class="w"> </span><span class="gp unselectable">...> </span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="c">_string</span><span class="w"> </span><span class="o">-></span><span class="w"> </span><span class="s">"two"</span><span class="w"> </span><span class="gp unselectable">...> </span><span class="w"> </span><span class="c">_ast</span><span class="p">,</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="o">-></span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="gp unselectable">...> </span><span class="k" data-group-id="7442467463-6">end</span><span class="p" data-group-id="7442467463-4">)</span><span class="w"> </span><span class="s">"one + two"</span></code></pre> </section> </div> <div class="detail" id="traverse/4"> <div class="detail-header"> <a href="#traverse/4" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">traverse(ast, acc, pre, post)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L242" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>traverse( <a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>(), (<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>() -> {<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>()}), (<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>() -> {<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>()}) ) :: {<a href="#t:t/0">t</a>(), <a href="typespecs.html#basic-types">any</a>()}</pre> </div> </div> <section class="docstring"> <p>Performs a depth-first traversal of quoted expressions using an accumulator.</p> </section> </div> <div class="detail" id="underscore/1"> <div class="detail-header"> <a href="#underscore/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">underscore(atom)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L1388" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> </div> <section class="docstring"> <p>Converts the given atom or binary to underscore format.</p> <p>If an atom is given, it is assumed to be an Elixir module, so it is converted to a binary and then processed.</p> <p>This function was designed to underscore language identifiers/tokens, that’s why it belongs to the <a href="Macro.html#content"><code class="inline">Macro</code></a> module. Do not use it as a general mechanism for underscoring strings as it does not support Unicode or characters that are not valid in Elixir identifiers.</p> <h2 id="underscore/1-examples" class="section-heading"> <a href="#underscore/1-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">underscore</span><span class="p" data-group-id="8788781503-1">(</span><span class="s">"FooBar"</span><span class="p" data-group-id="8788781503-1">)</span><span class="w"> </span><span class="s">"foo_bar"</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">underscore</span><span class="p" data-group-id="8788781503-2">(</span><span class="s">"Foo.Bar"</span><span class="p" data-group-id="8788781503-2">)</span><span class="w"> </span><span class="s">"foo/bar"</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">underscore</span><span class="p" data-group-id="8788781503-3">(</span><span class="nc">Foo.Bar</span><span class="p" data-group-id="8788781503-3">)</span><span class="w"> </span><span class="s">"foo/bar"</span></code></pre> <p>In general, <code class="inline">underscore</code> can be thought of as the reverse of <code class="inline">camelize</code>, however, in some cases formatting may be lost:</p> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">underscore</span><span class="p" data-group-id="2364880840-1">(</span><span class="s">"SAPExample"</span><span class="p" data-group-id="2364880840-1">)</span><span class="w"> </span><span class="s">"sap_example"</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">camelize</span><span class="p" data-group-id="2364880840-2">(</span><span class="s">"sap_example"</span><span class="p" data-group-id="2364880840-2">)</span><span class="w"> </span><span class="s">"SapExample"</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">camelize</span><span class="p" data-group-id="2364880840-3">(</span><span class="s">"hello_10"</span><span class="p" data-group-id="2364880840-3">)</span><span class="w"> </span><span class="s">"Hello10"</span></code></pre> </section> </div> <div class="detail" id="unescape_string/1"> <div class="detail-header"> <a href="#unescape_string/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">unescape_string(chars)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L499" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>unescape_string(<a href="String.html#t:t/0">String.t</a>()) :: <a href="String.html#t:t/0">String.t</a>()</pre> </div> </div> <section class="docstring"> <p>Unescapes the given chars.</p> <p>This is the unescaping behaviour used by default in Elixir single- and double-quoted strings. Check <a href="#unescape_string/2"><code class="inline">unescape_string/2</code></a> for information on how to customize the escaping map.</p> <p>In this setup, Elixir will escape the following: <code class="inline">\0</code>, <code class="inline">\a</code>, <code class="inline">\b</code>, <code class="inline">\d</code>, <code class="inline">\e</code>, <code class="inline">\f</code>, <code class="inline">\n</code>, <code class="inline">\r</code>, <code class="inline">\s</code>, <code class="inline">\t</code> and <code class="inline">\v</code>. Bytes can be given as hexadecimals via <code class="inline">\xNN</code> and Unicode Codepoints as <code class="inline">\uNNNN</code> escapes.</p> <p>This function is commonly used on sigil implementations (like <code class="inline">~r</code>, <code class="inline">~s</code> and others) which receive a raw, unescaped string.</p> <h2 id="unescape_string/1-examples" class="section-heading"> <a href="#unescape_string/1-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">unescape_string</span><span class="p" data-group-id="7601073335-1">(</span><span class="s">"example</span><span class="se">\\</span><span class="s">n"</span><span class="p" data-group-id="7601073335-1">)</span><span class="w"> </span><span class="s">"example</span><span class="se">\n</span><span class="s">"</span></code></pre> <p>In the example above, we pass a string with <code class="inline">\n</code> escaped and return a version with it unescaped.</p> </section> </div> <div class="detail" id="unescape_string/2"> <div class="detail-header"> <a href="#unescape_string/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">unescape_string(chars, map)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L545" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>unescape_string(<a href="String.html#t:t/0">String.t</a>(), (<a href="typespecs.html#basic-types">non_neg_integer</a>() -> <a href="typespecs.html#basic-types">non_neg_integer</a>() | false)) :: <a href="String.html#t:t/0">String.t</a>()</pre> </div> </div> <section class="docstring"> <p>Unescapes the given chars according to the map given.</p> <p>Check <a href="#unescape_string/1"><code class="inline">unescape_string/1</code></a> if you want to use the same map as Elixir single- and double-quoted strings.</p> <h2 id="unescape_string/2-map" class="section-heading"> <a href="#unescape_string/2-map" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Map </h2> <p>The map must be a function. The function receives an integer representing the codepoint of the character it wants to unescape. Here is the default mapping function implemented by Elixir:</p> <pre><code class="nohighlight makeup elixir"><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-1">(</span><span class="n">unicode</span><span class="p" data-group-id="9795580321-1">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="no">true</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-2">(</span><span class="n">hex</span><span class="p" data-group-id="9795580321-2">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="no">true</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-3">(</span><span class="sc">?0</span><span class="p" data-group-id="9795580321-3">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?0</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-4">(</span><span class="sc">?a</span><span class="p" data-group-id="9795580321-4">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\a</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-5">(</span><span class="sc">?b</span><span class="p" data-group-id="9795580321-5">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\b</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-6">(</span><span class="sc">?d</span><span class="p" data-group-id="9795580321-6">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\d</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-7">(</span><span class="sc">?e</span><span class="p" data-group-id="9795580321-7">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\e</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-8">(</span><span class="sc">?f</span><span class="p" data-group-id="9795580321-8">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\f</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-9">(</span><span class="sc">?n</span><span class="p" data-group-id="9795580321-9">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\n</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-10">(</span><span class="sc">?r</span><span class="p" data-group-id="9795580321-10">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\r</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-11">(</span><span class="sc">?s</span><span class="p" data-group-id="9795580321-11">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\s</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-12">(</span><span class="sc">?t</span><span class="p" data-group-id="9795580321-12">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\t</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-13">(</span><span class="sc">?v</span><span class="p" data-group-id="9795580321-13">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="sc">?\v</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="nf">unescape_map</span><span class="p" data-group-id="9795580321-14">(</span><span class="n">e</span><span class="p" data-group-id="9795580321-14">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">e</span></code></pre> <p>If the <code class="inline">unescape_map/1</code> function returns <code class="inline">false</code>, the char is not escaped and the backslash is kept in the string.</p> <p>Hexadecimals and Unicode codepoints will be escaped if the map function returns <code class="inline">true</code> for <code class="inline">?x</code>. Unicode codepoints if the map function returns <code class="inline">true</code> for <code class="inline">?u</code>.</p> <h2 id="unescape_string/2-examples" class="section-heading"> <a href="#unescape_string/2-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <p>Using the <code class="inline">unescape_map/1</code> function defined above is easy:</p> <pre><code class="nohighlight makeup elixir"><span class="nc">Macro</span><span class="o">.</span><span class="n">unescape_string</span><span class="w"> </span><span class="s">"example</span><span class="se">\\</span><span class="s">n"</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">unescape_map</span><span class="p" data-group-id="7290073068-1">(</span><span class="ni">&1</span><span class="p" data-group-id="7290073068-1">)</span></code></pre> </section> </div> <div class="detail" id="unpipe/1"> <div class="detail-header"> <a href="#unpipe/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">unpipe(expr)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L99" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>unpipe(<a href="Macro.html#t:t/0">Macro.t</a>()) :: [<a href="Macro.html#t:t/0">Macro.t</a>()]</pre> </div> </div> <section class="docstring"> <p>Breaks a pipeline expression into a list.</p> <p>The AST for a pipeline (a sequence of applications of <code class="inline">|></code>) is similar to the AST of a sequence of binary operators or function applications: the top-level expression is the right-most <code class="inline">:|></code> (which is the last one to be executed), and its left-hand and right-hand sides are its arguments:</p> <pre><code class="nohighlight makeup elixir"><span class="k">quote</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="w"> </span><span class="o">|></span><span class="w"> </span><span class="n">div</span><span class="p" data-group-id="7488492035-1">(</span><span class="mi">5</span><span class="p" data-group-id="7488492035-1">)</span><span class="w"> </span><span class="o">|></span><span class="w"> </span><span class="n">div</span><span class="p" data-group-id="7488492035-2">(</span><span class="mi">2</span><span class="p" data-group-id="7488492035-2">)</span><span class="w"> </span><span class="c1">#=> {:|>, _, [arg1, arg2]}</span></code></pre> <p>In the example above, the <code class="inline">|></code> pipe is the right-most pipe; <code class="inline">arg1</code> is the AST for <code class="inline">100 |> div(5)</code>, and <code class="inline">arg2</code> is the AST for <code class="inline">div(2)</code>.</p> <p>It’s often useful to have the AST for such a pipeline as a list of function applications. This function does exactly that:</p> <pre><code class="nohighlight makeup elixir"><span class="nc">Macro</span><span class="o">.</span><span class="n">unpipe</span><span class="p" data-group-id="0495959701-1">(</span><span class="k">quote</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="w"> </span><span class="o">|></span><span class="w"> </span><span class="n">div</span><span class="p" data-group-id="0495959701-2">(</span><span class="mi">5</span><span class="p" data-group-id="0495959701-2">)</span><span class="w"> </span><span class="o">|></span><span class="w"> </span><span class="n">div</span><span class="p" data-group-id="0495959701-3">(</span><span class="mi">2</span><span class="p" data-group-id="0495959701-3">)</span><span class="p" data-group-id="0495959701-1">)</span><span class="w"> </span><span class="c1">#=> [{100, 0}, {{:div, [], [5]}, 0}, {{:div, [], [2]}, 0}]</span></code></pre> <p>We get a list that follows the pipeline directly: first the <code class="inline">100</code>, then the <code class="inline">div(5)</code> (more precisely, its AST), then <code class="inline">div(2)</code>. The <code class="inline">0</code> as the second element of the tuples is the position of the previous element in the pipeline inside the current function application: <code class="inline">{{:div, [], [5]}, 0}</code> means that the previous element (<code class="inline">100</code>) will be inserted as the 0th (first) argument to the <a href="Kernel.html#div/2"><code class="inline">div/2</code></a> function, so that the AST for that function will become <code class="inline">{:div, [], [100, 5]}</code> (<code class="inline">div(100, 5)</code>).</p> </section> </div> <div class="detail" id="update_meta/2"> <div class="detail-header"> <a href="#update_meta/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">update_meta(quoted, fun)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L190" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>update_meta(<a href="#t:t/0">t</a>(), (<a href="typespecs.html#built-in-types">keyword</a>() -> <a href="typespecs.html#built-in-types">keyword</a>())) :: <a href="#t:t/0">t</a>()</pre> </div> </div> <section class="docstring"> <p>Applies the given function to the node metadata if it contains one.</p> <p>This is often useful when used with <a href="Macro.html#prewalk/2"><code class="inline">Macro.prewalk/2</code></a> to remove information like lines and hygienic counters from the expression for either storage or comparison.</p> <h2 id="update_meta/2-examples" class="section-heading"> <a href="#update_meta/2-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="n">quoted</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">quote</span><span class="w"> </span><span class="ss">line</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">sample</span><span class="p" data-group-id="0289153012-1">(</span><span class="p" data-group-id="0289153012-1">)</span><span class="w"> </span><span class="p" data-group-id="0289153012-2">{</span><span class="ss">:sample</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="0289153012-3">[</span><span class="ss">line</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p" data-group-id="0289153012-3">]</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="0289153012-4">[</span><span class="p" data-group-id="0289153012-4">]</span><span class="p" data-group-id="0289153012-2">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">update_meta</span><span class="p" data-group-id="0289153012-5">(</span><span class="n">quoted</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="nc">Keyword</span><span class="o">.</span><span class="n">delete</span><span class="p" data-group-id="0289153012-6">(</span><span class="ni">&1</span><span class="p">,</span><span class="w"> </span><span class="ss">:line</span><span class="p" data-group-id="0289153012-6">)</span><span class="p" data-group-id="0289153012-5">)</span><span class="w"> </span><span class="p" data-group-id="0289153012-7">{</span><span class="ss">:sample</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="0289153012-8">[</span><span class="p" data-group-id="0289153012-8">]</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="0289153012-9">[</span><span class="p" data-group-id="0289153012-9">]</span><span class="p" data-group-id="0289153012-7">}</span></code></pre> </section> </div> <div class="detail" id="validate/1"> <div class="detail-header"> <a href="#validate/1" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">validate(expr)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L448" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>validate(<a href="typespecs.html#built-in-types">term</a>()) :: :ok | {:error, <a href="typespecs.html#built-in-types">term</a>()}</pre> </div> </div> <section class="docstring"> <p>Validates the given expressions are valid quoted expressions.</p> <p>Checks the <a href="Macro.html#t:t/0"><code class="inline">Macro.t/0</code></a> for the specification of a valid quoted expression.</p> <p>It returns <code class="inline">:ok</code> if the expression is valid. Otherwise it returns a tuple in the form of <code class="inline">{:error, remainder}</code> where <code class="inline">remainder</code> is the invalid part of the quoted expression.</p> <h2 id="validate/1-examples" class="section-heading"> <a href="#validate/1-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">validate</span><span class="p" data-group-id="5416720701-1">(</span><span class="p" data-group-id="5416720701-2">{</span><span class="ss">:two_element</span><span class="p">,</span><span class="w"> </span><span class="ss">:tuple</span><span class="p" data-group-id="5416720701-2">}</span><span class="p" data-group-id="5416720701-1">)</span><span class="w"> </span><span class="ss">:ok</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">validate</span><span class="p" data-group-id="5416720701-3">(</span><span class="p" data-group-id="5416720701-4">{</span><span class="ss">:three</span><span class="p">,</span><span class="w"> </span><span class="ss">:element</span><span class="p">,</span><span class="w"> </span><span class="ss">:tuple</span><span class="p" data-group-id="5416720701-4">}</span><span class="p" data-group-id="5416720701-3">)</span><span class="w"> </span><span class="p" data-group-id="5416720701-5">{</span><span class="ss">:error</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="5416720701-6">{</span><span class="ss">:three</span><span class="p">,</span><span class="w"> </span><span class="ss">:element</span><span class="p">,</span><span class="w"> </span><span class="ss">:tuple</span><span class="p" data-group-id="5416720701-6">}</span><span class="p" data-group-id="5416720701-5">}</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">validate</span><span class="p" data-group-id="5416720701-7">(</span><span class="p" data-group-id="5416720701-8">[</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p" data-group-id="5416720701-8">]</span><span class="p" data-group-id="5416720701-7">)</span><span class="w"> </span><span class="ss">:ok</span><span class="w"> </span><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">validate</span><span class="p" data-group-id="5416720701-9">(</span><span class="p" data-group-id="5416720701-10">[</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="5416720701-11">{</span><span class="mi">4</span><span class="p" data-group-id="5416720701-11">}</span><span class="p" data-group-id="5416720701-10">]</span><span class="p" data-group-id="5416720701-9">)</span><span class="w"> </span><span class="p" data-group-id="5416720701-12">{</span><span class="ss">:error</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="5416720701-13">{</span><span class="mi">4</span><span class="p" data-group-id="5416720701-13">}</span><span class="p" data-group-id="5416720701-12">}</span></code></pre> </section> </div> <div class="detail" id="var/2"> <div class="detail-header"> <a href="#var/2" class="detail-link" title="Link to this function"> <span class="icon-link" aria-hidden="true"></span> <span class="sr-only">Link to this function</span> </a> <span class="signature">var(var, context)</span> <a href="https://github.com/elixir-lang/elixir/blob/v1.7.2/lib/elixir/lib/macro.ex#L233" class="view-source" rel="help" title="View Source"> <span class="icon-code" aria-hidden="true"></span> <span class="sr-only">View Source</span> </a> <div class="specs"> <pre>var(var, context) :: {var, [], context} when var: <a href="typespecs.html#basic-types">atom</a>(), context: <a href="typespecs.html#basic-types">atom</a>()</pre> </div> </div> <section class="docstring"> <p>Generates an AST node representing the variable given by the atoms <code class="inline">var</code> and <code class="inline">context</code>.</p> <h2 id="var/2-examples" class="section-heading"> <a href="#var/2-examples" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a> Examples </h2> <p>In order to build a variable, a context is expected. Most of the times, in order to preserve hygiene, the context must be <a href="Kernel.SpecialForms.html#__MODULE__/0"><code class="inline">__MODULE__/0</code></a>:</p> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">var</span><span class="p" data-group-id="0777229059-1">(</span><span class="ss">:foo</span><span class="p">,</span><span class="w"> </span><span class="bp">__MODULE__</span><span class="p" data-group-id="0777229059-1">)</span><span class="w"> </span><span class="p" data-group-id="0777229059-2">{</span><span class="ss">:foo</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="0777229059-3">[</span><span class="p" data-group-id="0777229059-3">]</span><span class="p">,</span><span class="w"> </span><span class="bp">__MODULE__</span><span class="p" data-group-id="0777229059-2">}</span></code></pre> <p>However, if there is a need to access the user variable, nil can be given:</p> <pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex> </span><span class="nc">Macro</span><span class="o">.</span><span class="n">var</span><span class="p" data-group-id="9436194930-1">(</span><span class="ss">:foo</span><span class="p">,</span><span class="w"> </span><span class="no">nil</span><span class="p" data-group-id="9436194930-1">)</span><span class="w"> </span><span class="p" data-group-id="9436194930-2">{</span><span class="ss">:foo</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="9436194930-3">[</span><span class="p" data-group-id="9436194930-3">]</span><span class="p">,</span><span class="w"> </span><span class="no">nil</span><span class="p" data-group-id="9436194930-2">}</span></code></pre> </section> </div> </section> <footer class="footer"> <p> <span class="line"> Built using <a href="https://github.com/elixir-lang/ex_doc" title="ExDoc" target="_blank" rel="help noopener">ExDoc</a> (v0.19.1), </span> <span class="line"> designed by <a href="https://twitter.com/dignifiedquire" target="_blank" rel="noopener" title="@dignifiedquire">Friedel Ziegelmayer</a>. </span> </p> </footer> </div> </div> </section> </div> <script src="dist/app-a0c90688fa.js"></script> </body> </html>