Elixirの基本制御構文
前回の記事から続いて、今回はElixirで利用する基本的な制御構文について学んでいきます。
if, unless/else
他のプログラミング言語で親しまれているif~elseは、Elixirでは以下のように記述します。
iex> if true do
...> "みえる"
...> else
...> "みえない"
...> end
"みえる"
ifをunlessに変えることで、条件を反転させることが出来ます。
case
case文は以下のように記述します。
iex> case {1, 2, 3} do
...> {4, 5, 6} ->
...> "この条件にはマッチしない"
...> {1, x, 3} ->
...> "この条件にマッチして、この文のスコープ変数xに2が代入される"
...> _ ->
...> "_ はどの条件にもマッチする"
...> end
"この条件にマッチして、この文のスコープ変数xに2が代入される"
cond
case文は幾つかの値の中でマッチするのもを探しだすのに便利ですが、幾つかの条件の中で最初にマッチするものを探し出したい場合もあります。 このようなときは、cond文を使用します。
iex> cond do
...> 2 + 2 == 5 ->
...> "ちがう"
...> 2 * 2 == 3 ->
...> "これもちがう"
...> 1 + 1 == 2 ->
...> "これだ!"
...> end
"これだ!"
上から評価されますが、最後までマッチされなかった時はエラーになります。
iex> cond do
...> 1 + 2 == 2 ->
...> "wow"
...> end
** (CondClauseError) no cond clause evaluated to a true value
do/end ブロック
Elixirもrubyのようにdo/endでブロックを定義することが出来ます。 do/endブロックで注意しないといけないのは、もっとも外側の関数の呼び出しに対してバインドされる点です。すなわち、以下の例は、
iex> is_number if true do
...> 1 + 2
...> end
以下のようにパースされることになります。
iex> is_number(if true) do
...> 1 + 2
...> end
** (RuntimeError) undefined function: if/1
また、ブロック内で定義された変数などは、ブロック外からはスコープ外になります。
raise
Elixirもrubyのようにraise句でエラーを発生させることが出来ます。
デフォルトはRuntimeError
です。
iex> raise "oops"
** (RuntimeError) oops
エラーを独自に定義して、raiseの引数で指定することも出来ます。
iex> defmodule MyError do
iex> defexception message: "default message"
iex> end
iex> raise MyError, message: "custom message"
** (MyError) custom message
rescue
エラーを補足するにはrescue句を利用します。
iex> try do
...> raise "oops"
...> rescue
...> e in RuntimeError -> e
...> end
%RuntimeError{message: "oops"}
throw/catch
Elixirで大域脱出を行うにはthrow/catchを利用します。 throwで値を投げ、catchで補足します。
iex> try do
...> Enum.each -50..50, fn(x) ->
...> if rem(x, 13) == 0, do: throw(x)
...> end
...> "Got nothing"
...> catch
...> x -> "Got #{x}"
...> end
"Got -39"
after
after句で、rubyのensureのように、try句の終了直前に必ず実行する処理を記述することが出来ます。
iex> try do
...> IO.puts "try!"
...> raise "raise!!"
...> after
...> IO.puts "after!!!"
...> end
try!
after!!!
** (RuntimeError) raise!!
exit
すべてのElixirコードは互いに通信し合うプロセス上で動いています。 プロセスが「自然死」する場合(例えば未処理の例外が起きた時)、exitシグナルを送ります。 また、手動でexitシグナルを送ることでプロセスを殺すこともできます。
try do
exit "急いで覚える"
catch
:exit, _ -> "Elixir"
end
"Elixir"
exitは前述のtry/catchで補足することも出来ます。
まとめ
Elixirの基本的な制御構文を学ぶことが出来ました。 より詳しく知りたい方は、以下の公式ドキュメントからよりカッコイイ書き方を知ることが出来ます。(外部サイトへ飛びます。)