View Source Routex.Branching (Phoenix Routes Extension Framework v0.3.0-alpha.4)
Provides a function to build branched variants of macro's
Summary
Functions
Takes a list of match patterns and creates the AST for branching variants for
all arities of macro
in module
by wrapping them in a case
statement.
Functions
Takes a list of match patterns and creates the AST for branching variants for
all arities of macro
in module
by wrapping them in a case
statement.
Args
patterns
: the match patterns to be used as case clausesmatch_binding
: ast inserted ascase [match_binding] do
module
: the module namemacro
: the macro nameopts
: list of options
Options
arities
: a list of arities to transform, default: all aritiesas
: name of the branching variant. default: the macro namearg_post
: function to calculate the replaced argument position. default: 0
The clauses and arguments can be transformed by providing MFA's. The
transformers receive as arguments the pattern
, the banched arg
and any
other argument provided in a
.
clause_transformer
: {m,f,a}. transforms a pattern; used as case clause in the macro body.arg_transformer
: {m,f,a}. transforms a branched argument; used in the macro body.
Example
We want to create a branching variant of the url
macro in Phoenix,.VerifiedRoutes
module. The original
macro generates code that simply prints the given path argument, but we want to it to write multiple clauses and
prefix the given argument based on the clause.
defmacro url(path, opts \ []) do -> quote do IO.puts(path) end
Given this code:
defmodule MyMod do
def transform_arg(pattern, arg, extra), do: "/" <> extra <> "/europe/" <> pattern <> "/" <> arg end
end
patterns = ["en", "nl"] match_binding = var!(external_var) arg_pos = fn arity -> arity - 1 end) arg_transformer = {MyMod, transform_arg, ["my_extra"]} opts = [as: :url, orig: :url_original, arg_pos: arg_pos, arg_transformer: arg_transformer]
branch_macro(patterns, match_binding, OriginalModule, :url, opts)
A new macro is build which outputs the AST of the original macro, wrapped in a case clause given transformed arguments.
defmacro url(path, opts \ []) do
quote do
case external_var do
"en" -> Original.Module.url( "/" <> "my_extra" <> "/europe/en/" <> path, opts)
"nl" -> Original.Module.url("/" <> "my_extra" <> "/europe/nl/" <> path, opts)
end
end
end
For more examples, please see the test module Routex.BranchingTest
.