ElixirのGetting Startedをやろうと思いまして、そのメモです。
はじめに
case
- 以前に束縛されてる値とマッチさせたい場合はピン演算子
^を使う
iex> case {1, 2, 3} do
...> {4, 5, 6} -> "foo"
...> {1, x, 3} -> "bar"
...> _ -> "baz"
...> end
"bar"
iex> x = 1
1
iex> case {1, 2, 3} do
...> {4, 5, 6} -> "foo"
...> {1, ^x, 3} -> "bar"
...> _ -> "baz"
...> end
"baz"
- ガードは
when - ガード句で使える式には制限がある(公式サイト参照)
- ガード句で発生したエラーは無視される
- どれにもマッチしなかった場合はエラーになる
iex> case {1, 2, 3} do
...> {1, x, 3} when x > 0 ->
...> "hogehoge"
...> _ ->
...> "hagehage"
...> end
"hogehoge"
iex> case 1 do
...> x when hd(x) -> "foo"
...> x -> "bar"
...> end
"bar"
iex> case :ok do
...> :error -> "error"
...> end
** (CaseClauseError) no case clause matching: :ok
- 匿名関数でも同じことができる
- 匿名関数では引数の数が同じでなければいけない
iex> f = fn
...> x, y when x > y -> x - y
...> x, y -> y - x
...> end
# Function<12.54118792/2 in :erl_eval.expr/5>
iex> f.(3, 2)
1
iex> f.(2, 3)
1
iex> f = fn
...> x, y -> x + y
...> x -> x
...> end
** (CompileError) iex:12: cannot mix clauses with different arities in function definition
(elixir) src/elixir_translator.erl:17: :elixir_translator.translate/2
cond
- 最初に真になるものを実行する
- 真になる条件式がなければエラーになる
iex> cond do
...> 2 + 2 == 5 -> "foo"
...> 2 * 2 == 3 -> "bar"
...> 1 + 1 == 2 -> "baz"
...> end
"baz"
iex> cond do
...> 2 + 2 == 5 -> "foo"
...> 2 * 2 == 3 -> "bar"
...> end
** (CondClauseError) no cond clause evaluated to a true value
if and unless
- マクロ (
if/2、unless/2)
iex> if true do
...> "This works!"
...> end
"This works!"
iex> unless true do
...> "This will never be seen"
...> end
nil
iex> if nil do
...> "hoge"
...> else
...> "hage"
...> end
"hage"
do/end blocks
- do/endブロックは式のまとまりを
do:オプションへ渡している - 実はキーワードリストを最後の引数に渡しているだけ
- キーワードリストはRubyと同じ感じ
iex> if(false, do: "foo", else: "bar")
"bar"