ジョインしたプロジェクトにてOK - LibraryをラッピングしたModuleを使用してるので、機能理解のために調べた内容のメモを落としておく。
Elegant error/exception handling in Elixir, with result monads.
result monads
とは、下記のことを指す。と考えておく。
{:ok, value} | {:error, reason}
このライブラリの設計思想について、Handling Errors in Elixir, No one say Monad.に書いてあるが、わかりやすいように、要約と適当にピックアップする
Tempted to say all elixir funcs should return a result tuple.
「すべての関数の返り値をresult tuple (= result monads)で返すべきだ」という少しばかり極端な思想が元になっている。
だが、この思想を実現するのが、OK
ライブラリになる。
具体的には下記の様になる
# 理想
case MyModule.flaky_method do
{:ok, value} -> IO.puts "All good value was: #{value}."
{:error, reason} -> IO.puts "Uh oh! Failed due to #{reason}."
end
もちろん、IO.puts/1
の返り値は:ok
なので、上記をiexとかで動かしてもパターンマッチでerrorとなる。
ひとまず、ゴールは「どのような関数を実行しても、result monad形式でreturnして処理をハンドリングする」ことだと考えるとわかりやすい。
そもそも、error/exceptionのハンドリングの主要なやりかたは大きく分けて2つの方法がある。
わかりやすい例として、Poisonライブラリで例にとる。
エンコード処理を行う関数encode
はPoison.encode/1
/ Poison.encode!/1
の2つが用意されている。
下記の通りとなる。
# monad
iex> case Poison.encode "asd" do
...> {:ok, value} -> value
...> {:error, value} -> value
...> end
"\"asd\"" # 処理が失敗しても、raiseしないで結果はresult monad形式でreturnするので、その結果をpattern-matchなどで補足して処理を分岐する
# raise
iex> try do
...> Poison.encode! {1,2}
...> rescue
...> e -> IO.inspect "error happen!!"
...> end
"error happen!!" # 処理が失敗したら、raiseするので、catch/rescueなどで補足して処理を分岐する
Elixirはfuncのreturnの形式をresult monadに強制することはなく、利用者にて好きな方を利用できるようなデザインが好まれる。
…ここに続き書く