[Elixir]パターンマッチを使って条件分岐を関数で分ける

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は、条件分岐を処理する方法として

  1. 関数定義
  2. case
  3. if
  4. cond

がありますが、個人的には上記の順で考える頭を作っていきたいなと思ってます。

テストシナリオを書くときも結構条件分岐は出てくるのですが、こういう感じで責務を分けることができると処理を集中できて良いなーとふと。

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s