11
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elixir パターンマッチングを使って、想定外の値は早い段階でエラーにしよう

Last updated at Posted at 2023-12-20

次のプログラムどう思いますか?

defmodule Extract do
  def get_value(string, desired_key) do
    parts = String.split(string, "&")

    Enum.find_value(parts, fn pair ->
      key_value = String.split(pair, "=")
      Enum.at(key_value, 0) == desired_key && Enum.at(key_value, 1)
    end)
  end
end

&で分割して、key=valueの組をつくって、desired_keyをキーとする値を求めるプログラムですね。
これで問題なく動きます。

達人プログラマーに確か、エラーは早い段階で検出する。エラーを隠して後の段階で問題が起きるような構造にしない。みたいなのがあったと思います。
このプログラムは、想定外のURL形式でもエラーになりません。

iex> Elixir101.get_value("name=Lucas&university=UFMG&lab=ASERG", "lab")
"ASERG"
iex> Elixir101.get_value("name=Lucas&university=institution=UFMG&lab=ASERG", "university")
"institution"

パターンマッチングを使って記述すると、key=value1=value2の場合、マッチングできないのでエラーになります。

defmodule Extract do
  def get_value(string, desired_key) do
    parts = String.split(string, "&")

    Enum.find_value(parts, fn pair ->
      [key, value] = String.split(pair, "=") # <= pattern matching
      key == desired_key && value
    end)
  end
end

記述も簡素になっていい感じです。

doctestで実行してみました。エラーになりました。

  1) doctest Elixir101.sample1/1 (1) (Elixir101Test)
     test/elixir101_test.exs:3
     ** (MatchError) no match of right hand side value: ["university", "institution", "UFMG"]
     stacktrace:
       (elixir101 0.1.0) lib/elixir101.ex:38: anonymous fn/2 in Elixir101.get_value2/2
       (elixir 1.14.4) lib/enum.ex:4239: Enum.find_value_list/3
       (for doctest at) lib/elixir101.ex:6: (test)

参照にしたElixirドキュメント
https://hexdocs.pm/elixir/1.16.0-rc.0/code-anti-patterns.html#non-assertive-pattern-matching

11
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?