Elixir 1.3では、 with に対して else や guards を使えるということで、少し試してみました。1.3の時と、1.2.4の時で無理やり書いた時。
http://tuvistavie.com/tokyo.ex
簡単な、 %{width: 10, height: 20} から値を取得して、それに対して幾つかのエラーケースを実践するという内容です。
1.3
さっとまとまる。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule S do | |
| @opts %{width: 10, height: 20} | |
| # iex> S.neko_success | |
| # {10, 20} | |
| def neko_success do | |
| with {:ok, width} <- Map.fetch(@opts, :width), | |
| {:ok, height} when height > 10 <- Map.fetch(@opts, :height) do | |
| IO.inspect {width, height} | |
| else | |
| {:ok, 20} -> IO.inspect "failed in {:ok, height}" | |
| {:error, message} -> IO.inspect {:error, message} | |
| other_error -> IO.inspect other_error | |
| end | |
| end | |
| # Map.fetch(@opts, :h) が失敗してしまう。 | |
| # iex> S.neko_fail_map | |
| # :error | |
| def neko_fail_map do | |
| with {:ok, width} <- Map.fetch(@opts, :width), | |
| {:ok, height} when height > 10 <- Map.fetch(@opts, :h) do | |
| IO.inspect {width, height} | |
| else | |
| {:ok, 20} -> IO.inspect "failed in {:ok, height}" | |
| {:error, message} -> IO.inspect {:error, message} | |
| other_error -> IO.inspect other_error | |
| end | |
| end | |
| # Map.fetchは全て正しいが、guardで失敗するので `with` では失敗する | |
| # iex> S.neko_fail_guard | |
| # "failed in {:ok, height}" | |
| def neko_fail_guard do | |
| with {:ok, width} <- Map.fetch(@opts, :width), | |
| {:ok, height} when height < 10 <- Map.fetch(@opts, :height) do | |
| IO.inspect {width, height} | |
| else | |
| {:ok, 20} -> IO.inspect "failed in {:ok, height}" | |
| {:error, message} -> IO.inspect {:error, message} | |
| other_error -> IO.inspect other_error | |
| end | |
| end | |
| end |
1.2.4
読みにくい感じ。不具合増えそうだ。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule S do | |
| @opts %{width: 10, height: 20} | |
| # iex> S.neko_success | |
| # {10, 20} | |
| def neko_success do | |
| result = | |
| with {:ok, width} <- Map.fetch(@opts, :width), | |
| {:ok, height} <- Map.fetch(@opts, :height) do | |
| case height do | |
| x when x > 10 -> {width, height} | |
| _ -> {:ok, height} | |
| end | |
| end | |
| case result do | |
| {:ok, 20} -> IO.inspect "failed in {:ok, height}" | |
| {:error, message} -> IO.inspect {:error, message} | |
| other_error when not is_tuple(other_error) -> IO.inspect other_error | |
| other -> IO.inspect result | |
| end | |
| end | |
| # Map.fetch(@opts, :h) が失敗してしまう。 | |
| # iex> S.neko_fail_map | |
| # :error | |
| def neko_fail_map do | |
| result = | |
| with {:ok, width} <- Map.fetch(@opts, :width), | |
| {:ok, height} <- Map.fetch(@opts, :h) do | |
| case height do | |
| x when x > 10 -> {width, height} | |
| _ -> {:ok, height} | |
| end | |
| end | |
| case result do | |
| {:ok, 20} -> IO.inspect "failed in {:ok, height}" | |
| {:error, message} -> IO.inspect {:error, message} | |
| other_error when not is_tuple(other_error) -> IO.inspect other_error | |
| other -> IO.inspect result | |
| end | |
| end | |
| # Map.fetchは全て正しいが、guardで失敗するので `with` では失敗する | |
| # iex> S.neko_fail_guard | |
| # "failed in {:ok, height}" | |
| def neko_fail_guard do | |
| result = | |
| with {:ok, width} <- Map.fetch(@opts, :width), | |
| {:ok, height} <- Map.fetch(@opts, :height) do | |
| case height do | |
| x when x < 10 -> {width, height} | |
| _ -> {:ok, height} | |
| end | |
| end | |
| case result do | |
| {:ok, 20} -> IO.inspect "failed in {:ok, height}" | |
| {:error, message} -> IO.inspect {:error, message} | |
| other_error when not is_tuple(other_error) -> IO.inspect other_error | |
| other -> IO.inspect result | |
| end | |
| end | |
| end |