一匹狼のelixirプログラム（.exs）に対してmix formatを利用して整形することを楽しむ

**ちはやふる神代も聞かず竜田川からくれなゐに水くくるとは**


---

Advent Calendar 2022 66日目[^1]の記事です。
I'm looking forward to 12/25,2022 :santa::santa_tone1::santa_tone2::santa_tone3::santa_tone4::santa_tone5:
私の[Advent Calendar 2022 一覧](https://docs.google.com/spreadsheets/d/1HQvFjagQLRPjOYAjDVzWp9S4b8dKixxvvaz_TtbZWto/edit#gid=1723448955)。

[^1]: @kaizen_nagoya さんの「[「@e99h2121 アドベントカレンダーではありますまいか Advent Calendar 2020」の改訂版ではありますまいか Advent Calendar 2022 １日目　Most Breakthrough Generator](https://qiita.com/kaizen_nagoya/items/49ebebee3a0377f3b59b)」から着想を得て、模倣いたしました。 

---



# はじめに

[Elixir](https://elixir-lang.org/)を楽しんでいますか:bangbang::bangbang::bangbang:

こんなことありませんか？
私はあります。
書きなぐり、使い捨てのちょっとした[Elixir](https://elixir-lang.org/)プログラムを作って、それを整形したいということはありませんか。


[Elixir](https://elixir-lang.org/)でソースコードの整形と言えば、 `mix format` です。
Mixタスク`mix new`して作成したプロジェクトではプロジェクトのルートで、`mix format`すると整形してくれます。
しかし`hoge.exs`のみがあるディレクトリにて、`mix format`をすると以下のエラーがでます。

```bash
$ ls
hoge.exs

$ mix format
** (Mix) Expected one or more files/patterns to be given to mix format or for a .formatter.exs file to exist with an :inputs or :subdirectories key
```

これを解決してみます。
というか、 **答えはエラーメッセージ** に書いてあります。

# `mix format hoge.exs`

`mix format hoge.exs` と実行してください。

```bash
$ mix format hoge.exs
```

この記事で伝えたいことはだいたい以上です。
もう少し情報を書き足します。

# What's `mix format`?

順番が前後しますが、`mix format`の説明をします。

## `mix format`

ドキュメントは[ここ](https://hexdocs.pm/mix/Mix.Tasks.Format.html)にあります。

https://hexdocs.pm/mix/Mix.Tasks.Format.html

たとえばソースコードが以下のようにインデントがそろっていない、関数呼び出しの`()`があったりなかったりと無秩序で混沌とした状態で存在しているとします。
世紀末です。
北斗の拳の世界です。


```elixir:hoge.exs
      defmodule Awesome do
  def fizz_buzz(n) do
do_fizz_buzz(n, rem(n, 3), rem(n, 5))
  end

  defp do_fizz_buzz(_n, 0, 0), do: "FizzBuzz"

  defp do_fizz_buzz(_n, 0, _), do: "Fizz"

  defp do_fizz_buzz(_n, _, 0), do: "Buzz"

  defp do_fizz_buzz(n, _, _), do: Integer.to_string n
end

Awesome.fizz_buzz(3) |> IO.puts
```

このプログラムは動きます。

```
elixir hoge.exs
Fizz
```

動きはします。
しかし美しくありません。
`mix format hoge.exs`してみます。

```elixir:hoge.exs
defmodule Awesome do
  def fizz_buzz(n) do
    do_fizz_buzz(n, rem(n, 3), rem(n, 5))
  end

  defp do_fizz_buzz(_n, 0, 0), do: "FizzBuzz"

  defp do_fizz_buzz(_n, 0, _), do: "Fizz"

  defp do_fizz_buzz(_n, _, 0), do: "Buzz"

  defp do_fizz_buzz(n, _, _), do: Integer.to_string(n)
end

Awesome.fizz_buzz(3) |> IO.puts()
```

どうでしょう。
私には「美しく」みえます。
人の美意識はそれぞれ異なりますし、異なるからおもしろいのです。
あなたの内なる声に従ってください。

## What's `mix`?

これまた順番が前後してしまいました。
`mix`を説明します。

`mix format`の`mix`とは何でしょうか。
[Elixir](https://elixir-lang.org/)をインストールすると付いてくる**ビルドツール**です。

ドキュメントは[ここ](https://hexdocs.pm/mix/Mix.html)にあります。

https://hexdocs.pm/mix/Mix.html

> Mix is a build tool that provides tasks for creating, compiling, and testing Elixir projects, managing its dependencies, and more.

冒頭、**ビルドツール**ですと言いました。
一言でいうとそういうことになります。
意味するところはもう少し広いです。
その意味するところは上記の[公式ドキュメント](https://hexdocs.pm/mix/Mix.html)をご確認ください。

ここでは[Elixir](https://elixir-lang.org/)開発を楽しむ上でよくつかうMixタスクを列挙しておきます。

- mix new
- mix deps.get
- mix format
- mix test
- mix phx.new ※ [Phoenix](https://www.phoenixframework.org/)
- mix phx.server ※ [Phoenix](https://www.phoenixframework.org/)
- mix nerves.new ※ [Nerves](https://www.nerves-project.org/)


Mixタスク一覧は、`mix help`コマンドでみれます。
それぞれのタスクのヘルプは、`mix help new`のように実行することで確認できます。
探検してみてください。

# `mix format`

ここでひとつの疑問を持った方がいるかもしれません。
「そういえば、どうしてMixタスク`mix new`や[Phoenix](https://www.phoenixframework.org/)アプリではファイル指定なぞしなくても`mix format`だけで整形を楽しめたのであろうか？」という疑問です。

お答えします。

`.formatter.exs`ファイルです。
`.formatter.exs`ファイルに、どの[Elixir](https://elixir-lang.org/)ファイルを対象として`mix format`するのかのルールが書いてあります。
Mixタスク`mix format`の内部実装は、`.formatter.exs`ファイルを参照しています。

たとえばMixタスク`mix phx.new`して作った[Phoenix](https://www.phoenixframework.org/)アプリはデフォルトで以下が用意されています。

```elixir:.formatter.exs
[
  import_deps: [:ecto, :phoenix],
  inputs: ["*.{ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{ex,exs}"],
  subdirectories: ["priv/*/migrations"]
]
```

[Mix.install/2](https://hexdocs.pm/mix/Mix.html#install/2)を使ったサンプル集である[wojtekmach/mix_install_examples](https://github.com/wojtekmach/mix_install_examples)は以下がおいてあります。
ディレクトリ直下の`.exs`を対象に`mix format`できます。


```elixir:.formatter.exs
# Used by "mix format"
[
  inputs: ["*.exs"]
]
```

これをみて、「一匹狼のelixirプログラム（.exs）をmix format」できると私はわかりました。
一体どうなっているのだろう？　とおもって、[公式ドキュメント](https://hexdocs.pm/mix/Mix.Tasks.Format.html)をみた次第です。
そしてこの記事は、Mixタスク`mix format`の[公式ドキュメント](https://hexdocs.pm/mix/Mix.Tasks.Format.html)へのリンクを示したということだけの記事です。
言いたいことはこれだけです。


詳しい説明は省きます。
私からはいたしますまい。
ちゃんとした説明を私ができないという事情もあります。

[ドキュメント](https://hexdocs.pm/mix/Mix.Tasks.Format.html)をご確認ください。

https://hexdocs.pm/mix/Mix.Tasks.Format.html

ここにすべてが書いてあります。





---

# Wrapping up :lgtm::lgtm::lgtm::lgtm::lgtm:

本日はMixタスク[mix format](https://hexdocs.pm/mix/Mix.Tasks.Format.html)の話を書きました。
みなさまのお役に立てれば幸いです。

言いたいことは、「[公式ドキュメント](https://hexdocs.pm/mix/Mix.Tasks.Format.html)をご参照ください」ということです。
このコラムはあなたの変わりに、「Mixタスク[mix format](https://hexdocs.pm/mix/Mix.Tasks.Format.html)の[公式ドキュメント](https://hexdocs.pm/mix/Mix.Tasks.Format.html)を見つけてきました」という記事でございました。

:lgtm: やコメントは、励みになりますし、私はちょっぴりハゲています。

Enjoy [Elixir](https://elixir-lang.org/):bangbang::bangbang::bangbang:
<font color="purple">$\huge{Enjoy\ Elixir🚀}$</font>



以上です。