Search⌘ K
AI Features

Leveraging the Virtual Machine’s Pattern Matching Engine

Explore how to leverage the Erlang VM's powerful pattern matching engine in Elixir to implement assertion macros. Learn to create maintainable meta-programming code by proxying assertions to outside functions, managing code generation efficiently, and improving test modularity. This lesson helps you understand key techniques to extend Elixir’s testing capabilities with metaprogramming.

We'll cover the following...

The Assertion module

Now that our assert macro is in place, we can implement the proxy assert functions in a new Assertion.Test module. The Assertion.Test module will carry out the work of performing the assertions and running our tests.

When we find ourselves at a stage in code where we’ve proxied out to a function that we are about to implement, try to think about how pattern matching can help guide our implementation. Let’s see how to use the virtual machine while doing it.

We’ll change the project used in our previous example in the following way:

defmodule Assertion do

  defmacro assert({operator, _, [lhs, rhs]}) do
    quote bind_quoted: [operator: operator, lhs: lhs, rhs: rhs] do
      Assertion.Test.assert(operator, lhs, rhs)                     
    end
  end
end

defmodule Assertion.Test do                                         
  def assert(:==, lhs, rhs) when lhs == rhs do
    IO.write "."
  end
  def assert(:==, lhs, rhs) do
    IO.puts """
    FAILURE:
      Expected:       #{lhs}
      to be equal to: #{rhs}
    """
  end

  def assert(:>, lhs, rhs) when lhs > rhs do
    IO.write "."
  end
  def assert(:>, lhs, rhs) do
    IO.puts """
    FAILURE:
      Expected:           #{lhs}
      to be greater than: #{rhs}
    """
  end
end
Defining `Assertion` module with `assert` macro.

By ...