Do you want to pick up from where you left of?
Take me there

ドキュメント

Elixirコードのドキュメント。

注釈

どれくらいコメントを書くとか、何がドキュメントの質を決めるとかいう話はプログラミングの世界では結論の出ていない問題です。しかし自身やそのコードベースに関わる人たちにとって大切だという点では、誰もが同意できるでしょう。

Elixirはドキュメントを 第一級市民 として扱い、プロジェクトのドキュメントにアクセスしたり生成したりするために各種の関数を用意しています。Elixirコアはコードベースに注釈を付けるために多くの異なった属性を提供しています。3つの方法を見ていきましょう:

インラインドキュメント

おそらく最も単純にコードコメントを付ける方法はインラインコメントを用いることです。RubyやPythonと同じように、Elixirのインラインコメントは # で示します。あなたがいた環境によって、よくパウンドハッシュ などとして知られています。

このElixirスクリプトを見てください (greeting.exs):

# コンソールに 'Hello, chum.' と出力します。
IO.puts "Hello, " <> "chum."

Elixirはこのスクリプトを実行する際に、 # からその行末までを全て無視し、不要なデータとみなします。スクリプトの処理やパフォーマンスには影響しないかもしれませんが、コメントを読んだプログラマが挙動を理解するにはあまり明確ではないでしょう。単一行コメントの乱用は避けるように心がけてください!コードベースへのポイ捨ては誰かにとって好ましくない悪夢となるかもしれません。控えめに用いるのが最良です。

モジュールのドキュメント

@moduledoc アノテータはインラインドキュメントをモジュールレベルで行うためのものです。通常はファイル最上部で defmodule の宣言をした直後に置かれます。次の例は @moduledoc 修飾子内の1行コメントを示します。

defmodule Greeter do
  @moduledoc """
  ある人を歓迎する `hello/1` 関数を提供します
  """

  def hello(name) do
    "Hello, " <> name
  end
end

このモジュールドキュメントには、IEx内で h ヘルパー関数を用いてアクセスすることができます。 Greeter モジュールを新しいファイル greeter.ex に入れてコンパイルすると、これを自分で確認できます。

iex> c("greeter.ex", ".")
[Greeter]

iex> h Greeter

                Greeter

ある人を歓迎する `hello/1` 関数を提供します

_注記_:mixプロジェクトのコンテキスト内で作業している場合、上記のようにファイルを手動でコンパイルする必要はありません。mixプロジェクトで作業している場合は、 iex -S mix を使用して現在のプロジェクトのIExコンソールをロードできます。

関数のドキュメント化

Elixirがモジュールレベルで注釈する機能を与えてくれるのと同じく、関数をドキュメント化するためにも似たような注釈が可能です。 @doc アノテータは関数レベルでのインラインドキュメントを行うためのものです。 @doc アノテータは注釈を付けたい関数の直前に置かれます。

defmodule Greeter do
  @moduledoc """
  ...
  """

  @doc """
  Helloメッセージを表示します

  ## パラメータ

    - name: 人名を表現する文字です。

  ## 例

      iex> Greeter.hello("Sean")
      "Hello, Sean"

      iex> Greeter.hello("pete")
      "Hello, pete"

  """
  @spec hello(String.t()) :: String.t()
  def hello(name) do
    "Hello, " <> name
  end
end

IExを再び起動し、上記の関数をモジュール名付きで ヘルパーコマンド (h) に渡すと、次のような結果が得られるはずです:

iex> c("greeter.ex")
[Greeter]

iex> h Greeter.hello

                def hello(name)

Helloメッセージを表示します

パラメータ

   name: 人名を表現する文字です



    iex> Greeter.hello("Sean")
    "Hello, Sean"

    iex> Greeter.hello("pete")
    "Hello, pete"

iex>

ドキュメント内でマークアップが使え、ターミナルがきちんと描画したことに気づきましたか?本当にクールで、Elixirの広大なエコシステムへの素晴らしい追加機能であることは置いておくとしても、ExDocがその場でHTMLドキュメントを生成してくれるのを見ると、人はより興味を持ちます。

注: @spec アノテーションはコードの静的解析に使われます。詳しい説明は仕様と型を参照してください。

ExDoc

ExDocは公式のElixirプロジェクトで、GitHub で見つけることができます。ExDocは HTML (HyperText Markup Language) とオンラインドキュメント を生成します。最初に、アプリケーションのためにMixプロジェクトを作成しましょう:

$ mix new greet_everyone

* creating README.md
* creating .gitignore
* creating .formatter.exs
* creating mix.exs
* creating lib
* creating lib/greet_everyone.ex
* creating test
* creating test/test_helper.exs
* creating test/greet_everyone_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd greet_everyone
    mix test

Run "mix help" for more commands.

$ cd greet_everyone

次に @doc アノテータのレッスンからコードをコピー & ペーストして、 lib/greeter.ex ファイルに保存し、コマンドラインから全てがまだ動くことを確認します。Mixプロジェクト内で作業をするのでIExを先ほどとは若干異なり、 iex -S mix コマンドで起動する必要があります:

iex> h Greeter.hello

                def hello(name)

Helloメッセージを表示します

パラメータ

   name: 人名を表現する文字です



    iex> Greeter.hello("Sean")
    "Hello, Sean"

    iex> Greeter.hello("pete")
    "Hello, pete"

インストール

全てがうまくいき、上記のような出力が表示されていれば、ExDocの構築準備ができていることを意味します。 mix.exs ファイルに、 :ex_doc の依存関係を追加してください:

  def deps do
    [{:ex_doc, "~> 0.21", only: :dev, runtime: false}]
  end

only: :dev というキーバリューのペアを指定することで、本番環境では :ex_doc の依存関係パッケージをダウンロードしたりコンパイルしたりしないようにします。

ex_doc は、Earmarkという別のライブラリも追加します。

Earmarkは、ExDocが @moduledoc および @doc 内のドキュメントを美しいHTMLに変換するために使用するElixirプログラミング言語用のMarkdownパーサーです。

ここで注記しておくと、必要に応じてマークアップツールをCmarkに変更することもできます。ただし、ここを読み、若干の追加設定を行う必要があるでしょう。このチュートリアルでは、単にEarmarkを用います。

ドキュメント生成

さて続けましょう。コマンドラインから次の2つのコマンドを実行してください:

$ mix deps.get # ExDocとEarmarkを取得します。
$ mix docs # ドキュメントを作成します。

Docs successfully generated.
View them at "doc/index.html".

全てが計画どおりなら、上記の例にあるような出力メッセージが表示されるでしょう。次に、Mixプロジェクト内部を見ていきましょう。 doc/ ディレクトリがあるはずです。中身は生成されたドキュメントになります。インデックスページをブラウザで開くと、以下のように表示されるはずです:

ExDoc Screenshot 1

Earmarkがマークダウンを描画し、ExDocがわかりやすいフォーマットで表示してくれています。

ExDoc Screenshot 2

これでGithubや自身のウェブサイト、あるいは非常に一般的な HexDocs へデプロイすることができるようになりました。

ベストプラクティス

ドキュメントの追加は、言語のベストプラクティスガイドラインに加えられるべきです。Elixirはかなり若い言語なので、エコシステムの成長に伴っていまだに多くの新基準が発見されている状況です。それでも、Elixirのコミュニティはベストプラクティスの確立に尽力しています。ベストプラクティスについてさらなる詳細を知りたい場合は、The Elixir Style Guide をご覧ください。

defmodule Greeter do
  @moduledoc """
  これは良いドキュメントです。
  """

end
defmodule Greeter do
  @moduledoc false

end
defmodule Greeter do
  @moduledoc """
  ...

  このモジュールには `hello/1` 関数もあります。
  """

  def hello(name) do
    IO.puts("Hello, " <> name)
  end
end
defmodule Greeter do
  @moduledoc """
  ...

  このモジュールには `hello/1` 関数もあります。
  """

  alias Goodbye.bye_bye
  # などなど...

  def hello(name) do
    IO.puts("Hello, " <> name)
  end
end
defmodule Greeter do
  @moduledoc """
  ...
  """

  @doc """
  Helloメッセージを表示します

  ## パラメータ

  - name: 人名を表現する文字です。

  ## 例

      iex> Greeter.hello("Sean")
      "Hello, Sean"

      iex> Greeter.hello("pete")
      "Hello, pete"

  """
  @spec hello(String.t()) :: String.t()
  def hello(name) do
    "Hello, " <> name
  end
end
間違いを報告したい、あるいはこのレッスンに貢献したい? このレッスンをGitHubで編集しよう!