View Source Matcha (Matcha v0.1.7)

First-class match specifications for Elixir.

synopsis

Synopsis

Matcha offers tight integration with Elixir and match specifications.

Match specifications are a BEAM VM feature that can execute de-structuring, pattern matching, and re-structring operations very close-to-the-metal. They can be used to efficiently:

However, they are notoriously difficult to compose and use. Matcha makes this intuitive with ergonomic macros to compose them, and a high-level API with which to use them.

guides

Guides

Check out the interactive usage guides, including using Matcha for:

examples

Examples

# Turn Elixir code into a match specification,
#  then use it to filter/map some data
iex> require Matcha
...> Matcha.spec do
...>   {x, y, z} -> x + y + z
...> end
...> |> Matcha.Spec.run!([
...>   {1, 2, 3},
...>   {1, 2},
...>   {1, 2, 3, 4},
...>   {4, 5, 6}
...> ])
[6, 15]

This is one way to run test and develop match specifications, but they truly shine in table and tracing applications!

Link to this section Summary

Functions

Builds a Matcha.Pattern that represents a pattern matching operation on a given input.

Builds a Matcha.Spec that represents a destructuring, pattern matching, and re-structuring operation on a given input.

Traces function calls to module, executing a spec on matching arguments.

Link to this section Functions

Link to this macro

pattern(pattern)

View Source (macro)
@spec pattern(Macro.t()) :: Macro.t()

Builds a Matcha.Pattern that represents a pattern matching operation on a given input.

For more information on match patterns, consult the Matcha.Pattern docs.

examples

Examples

iex> require Matcha
...> pattern = Matcha.pattern({x, y, x})
#Matcha.Pattern<{:"$1", :"$2", :"$1"}>
iex> Matcha.Pattern.match?(pattern, {1, 2, 3})
false
iex> Matcha.Pattern.match?(pattern, {1, 2, 1})
true
Link to this macro

spec(context \\ Matcha.Context.FilterMap, spec)

View Source (macro)
@spec spec(Matcha.Context.t(), Macro.t()) :: Macro.t()

Builds a Matcha.Spec that represents a destructuring, pattern matching, and re-structuring operation on a given input.

The context may be :filter_map, :match, :table, :trace, or a Matcha.Context module. This is detailed in the Matcha.Context docs.

For more information on match specs, consult the Matcha.Spec docs.

examples

Examples

iex> require Matcha
...> Matcha.spec do
...>   {x, y, x}
...>     when x > y and y > 0
...>       -> x
...>   {x, y, y}
...>     when x < y and y < 0
...>       -> y
...> end
#Matcha.Spec<[{{:"$1", :"$2", :"$1"}, [{:andalso, {:>, :"$1", :"$2"}, {:>, :"$2", 0}}], [:"$1"]}, {{:"$1", :"$2", :"$2"}, [{:andalso, {:<, :"$1", :"$2"}, {:<, :"$2", 0}}], [:"$2"]}], context: Matcha.Context.FilterMap>
Link to this macro

trace_calls(module, function, opts \\ [], spec)

View Source (macro)

Traces function calls to module, executing a spec on matching arguments.

Tracing is a powerful feature of the BEAM VM, allowing for near zero-cost monitoring of what is happening in running systems. The functions in Matcha.Trace provide utilities for accessing this functionality.

One of the most powerful forms of tracing uses match specifications: rather that just print information on when a certain function signature with some number of arguments is invoked, they let you:

  • dissect the arguments in question with pattern-matching and guards
  • take special actions in response (documented in Matcha.Context.Trace)

This macro is a shortcut for constructing a spec with the :trace context via Matcha.spec/2, and tracing the specified module and function with it via Matcha.Trace.calls/4.

For more information on tracing in general, consult the Matcha.Trace docs.

examples

Examples

iex> require Matcha
...> Matcha.trace_calls(Enum, :join, limit: 3) do
...>   [_enumerable] -> message("using default joiner")
...>   [_enumerable, ""] -> message("using default joiner (but explicitly)")
...>   [_enumerable, _custom] -> message("using custom joiner")
...> end
...> Enum.join(1..3)
# Prints a trace message with "using default joiner" appended
"123"
iex> Enum.join(1..3, "")
# Prints a trace message with "using default joiner (but explicitly)" appended
"123"
iex> Enum.join(1..3, ", ")
# Prints a trace message with "using custom joiner" appended
"1, 2, 3"