LoginSignup
7
2

More than 5 years have passed since last update.

マクロを使ってドキュメントやtypespecsを生成する

Last updated at Posted at 2017-12-23

Elixirのマクロで普通にできたので書きます。

はじめに

Elixirはモジュール内で以下のようにしてマクロで関数を定義できます。

defmodule Sample do
  def unquote(:hoge)() do
    unquote(1)
  end
end
iex(1)> Sample.hoge()
1

どうも、

def unquote(シンボル)() do
  unquote()
end

という処理が走っていればOKのようです。

Enum.eachで複数定義してみる

defmodule Sample do
  [a: 1, b: 2, c: 3]
  |> Enum.each(fn {sym, num} ->
    def unquote(sym) do
      unquoite(num)
    end
  end)
end
iex(1)> Sample.a()
1
iex(1)> Sample.b()
2
iex(1)> Sample.c()
3

ドキュメンテーション

次はドキュメンテーション込みで生成してみましょう。

exsファイルだとドキュメントがコンパイルされないようなので、mix new sampleでもしてからiex -S mixすると楽だと思います。

defmodule Sample do
  [a: 1, b: 2, c: 3]
  |> Enum.each(fn {sym, num} ->
    @doc ~s"""
    #{sym} returns #{num}.
    """
    def unquote(sym) do
      unquoite(num)
    end
  end)
end
iex(1)> h Sample.a()
a returns 1.
iex(2)> h Sample.b()
b returns 2.
iex(3)> h Sample.c()
c returns 3.

いい感じです。

Typespecs

続いてtypespec

defmodule Sample do
  [a: 1, b: 2, c: 3]
  |> Enum.each(fn {sym, num} ->
    @doc ~s"""
    #{sym} returns #{num}.
    """
    @spec unquote(unit)() :: number
    def unquote(sym) do
      unquoite(num)
    end
  end)
end
iex(1)> s Sample.a
@spec a() :: number()
iex(2)> s Sample.b
@spec b() :: number()
iex(3)> s Sample.c
@spec c() :: number()

いい感じです。ex_docを入れてmix docsすればナイスなドキュメンテーションとtypespecが生成されることでしょう。

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2