OK elixir Library

context

ジョインしたプロジェクトにてOK - LibraryをラッピングしたModuleを使用してるので、機能理解のために調べた内容のメモを落としておく。

whats is ok library?

Elegant error/exception handling in Elixir, with result monads.

  • error/exceptionのハンドリング用のライブラリ
  • result monadsを取り扱う

result monads とは、下記のことを指す。と考えておく。

  {:ok, value} | {:error, reason}

OK library の設計思想

このライブラリの設計思想について、Handling Errors in Elixir, No one say Monad.に書いてあるが、わかりやすいように、要約と適当にピックアップする

すべての返り値はResult 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 handling

そもそも、error/exceptionのハンドリングの主要なやりかたは大きく分けて2つの方法がある。

  1. monad
  2. raise

わかりやすい例として、Poisonライブラリで例にとる。

エンコード処理を行う関数encodePoison.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に強制することはなく、利用者にて好きな方を利用できるようなデザインが好まれる。

How to use OK Library

…ここに続き書く