Help us understand the problem. What is going on with this article?

Elixirのdefmacro内の__MODULE__はどのモジュールを指しているのか

More than 3 years have passed since last update.

Elixirのdefmacro内のコードには__MODULE__というマクロが頻出しますが、これが「マクロが定義されているモジュール」を指しているのか、それとも「マクロを呼び出しているモジュール」を指しているのか、ちょっと分かりにくいので下記のように実験してみました。

defmodule A do
  defmacro __using__(_opts) do
    IO.inspect "__MODULE__ = #{__MODULE__}"
    IO.inspect "unquote(__MODULE__) = #{unquote(__MODULE__)}"
    quote do
      IO.inspect "__MODULE__ = #{__MODULE__}"
      IO.inspect "unquote(__MODULE__) = #{unquote(__MODULE__)}"
      @before_compile unquote(__MODULE__)
    end
  end
  defmacro __before_compile__(env) do
    IO.inspect "env.module == #{env.module}"
  end
end

defmodule B do
  use A
end

iex上での実行結果は下記のようになります。

"__MODULE__ = Elixir.A"
"unquote(__MODULE__) = Elixir.A"
"__MODULE__ = Elixir.B"
"unquote(__MODULE__) = Elixir.A"
"env.module == Elixir.B"

要するに、defmacro内のquote式内で__MODULE__と書いた場合のみ呼び出し側のモジュールが参照され、それ以外の場合はマクロが定義されているモジュールが参照される、ということになるようです。

attributeを操作する関数(Module.register_attribute等)を使う場合は「呼び出し側のモジュール」を参照する必要がありますが、それ以外は基本的に「マクロが定義されているモジュール」を参照するケースの方が多いと思いますので、「基本的にはunquote(__MODULE__)を使う、attributeを操作するときだけ__MODULE__を使う」というような覚え方でも良さそうな印象です。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away