Elixirは関数定義の引数に対してパターンマッチを利用できます。
ちょっと、ちゃんとElixirっぽくしようということで使ってみました。
対象は以下。
https://github.com/KazuCocoa/simple_app_reporter_ex/blob/master/lib/reporter.ex
get_body_json という関数は、HTTPoisonのレスポンスを引数として、そのレスポンスに適した処理を行うというものです。
修正前
caseを使って、得られたHTTPoisonのレスポンス毎に処理を分けています。
1つの関数内で条件が分岐するので、関数内の処理が必然的に多くなります。
defp get_body_json(response) do
case response do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
body
{:ok, %HTTPoison.Response{status_code: 404}} ->
~s({"status_code": "404", "message": "Not found items."})
{:error, %HTTPoison.Error{reason: reason}} ->
IO.inspect reason
end
end
修正後
関数定義の引数でパターンマッチを利用しています。上記の case における条件がそのまま関数定義になります。
この結果、 get_body_json() という関数に値を与えると、引数のHTTPoisonの状態によってElixirが勝手に処理を分けます。
1つの関数が過度に肥大化しなくなり、関数が最低限の責務を持つようにプログラムできるのが良いですね 🙂
defp get_body_json({:ok, %HTTPoison.Response{status_code: 200, body: body}}), do: body
defp get_body_json({:ok, %HTTPoison.Response{status_code: 404}}), do: ~s({"status_code": "404", "message": "Not found items."})
defp get_body_json({:error, %HTTPoison.Error{reason: reason}}), do: IO.inspect reason
締め
Elixirは、条件分岐を処理する方法として
- 関数定義
caseifcond
がありますが、個人的には上記の順で考える頭を作っていきたいなと思ってます。
テストシナリオを書くときも結構条件分岐は出てくるのですが、こういう感じで責務を分けることができると処理を集中できて良いなーとふと。