Routex.Branching (Routex v1.3.1)
View SourceProvides 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] domodule: 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) endGiven 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
endFor more examples, please see the test module Routex.BranchingTest.