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


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


Advent Calendar 2022 66日目1の記事です。
I'm looking forward to 12/25,2022
私のAdvent Calendar 2022 一覧


はじめに

Elixirを楽しんでいますか

こんなことありませんか?
私はあります。
書きなぐり、使い捨てのちょっとしたElixirプログラムを作って、それを整形したいということはありませんか。

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

$ 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 と実行してください。

$ mix format hoge.exs

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

What's mix format?

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

mix format

ドキュメントはここにあります。

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

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してみます。

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 formatmixとは何でしょうか。
Elixirをインストールすると付いてくるビルドツールです。

ドキュメントはここにあります。

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

冒頭、ビルドツールですと言いました。
一言でいうとそういうことになります。
意味するところはもう少し広いです。
その意味するところは上記の公式ドキュメントをご確認ください。

ここではElixir開発を楽しむ上でよくつかうMixタスクを列挙しておきます。

  • mix new
  • mix deps.get
  • mix format
  • mix test
  • mix phx.new ※ Phoenix
  • mix phx.server ※ Phoenix
  • mix nerves.new ※ Nerves

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

mix format

ここでひとつの疑問を持った方がいるかもしれません。
「そういえば、どうしてMixタスクmix newPhoenixアプリではファイル指定なぞしなくてもmix formatだけで整形を楽しめたのであろうか?」という疑問です。

お答えします。

.formatter.exsファイルです。
.formatter.exsファイルに、どのElixirファイルを対象としてmix formatするのかのルールが書いてあります。
Mixタスクmix formatの内部実装は、.formatter.exsファイルを参照しています。

たとえばMixタスクmix phx.newして作ったPhoenixアプリはデフォルトで以下が用意されています。

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

Mix.install/2を使ったサンプル集であるwojtekmach/mix_install_examplesは以下がおいてあります。
ディレクトリ直下の.exsを対象にmix formatできます。

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

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

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

ドキュメントをご確認ください。

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


Wrapping up

本日はMixタスクmix formatの話を書きました。
みなさまのお役に立てれば幸いです。

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

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

Enjoy Elixir
$\huge{Enjoy\ Elixir🚀}$

以上です。

  1. @kaizen_nagoya さんの「「@e99h2121 アドベントカレンダーではありますまいか Advent Calendar 2020」の改訂版ではありますまいか Advent Calendar 2022 1日目 Most Breakthrough Generator」から着想を得て、模倣いたしました。