mmag

ハマったことメモなど

Elixirマクロの展開後コードを見る

Elixirのマクロはコンパイル時にバーっと展開されるわけですが、本当に自分が望んだ形に展開されてるのか、不安になって眠れない夜もあるでしょう。

ということで、複雑なマクロを書いちゃったときはテストで展開後のコードをチェックするのも1つの手です。

# lib/my_module.ex

defmodule MyModule do
  defmacro my_macro do
    quote do
      ...  # 略
    end
  end
end
# test/test_helper.exs

ExUnit.start

defmodule TestHelper do
  defmacro macro_to_code(macro) do
    macro |> Macro.expand(__CALLER__) |> Macro.to_string
  end
end
# test/my_module_test.exs

defmodule MyModuleTest do
  use ExUnit.Case
  import TestHelper
  import MyMacro

  test "my_macro" do
    expanded = macro_to_code(my_macro)  # 文字列が返る
    assert expanded =~ ~r/.../
  end
end

挙動のテストと併せて、これで安心ですね。文字列ではなくASTの形で返してほしいときは、

defmacro macro_to_ast(macro) do
  macro |> Macro.expand(__CALLER__) |> Macro.escape
end

でできます。

はー どようび。