Elixirのチートシートを作ろう #9 制御構造その１



# 1. OverView

さて、制御構造です。ifだ、分かりやすい奴…
いやぁ、whileもforもなくて、どーなるかと思ってた。

それでも、今まで、さんざんEnumで以下みたいな処理と同等の関数を見てきましたね。

```
for( TGT in list ){
    if(list[TGT] == "なんたら"){ printf("かんたら\n")}
}
```
これで、ifとか要らん気になりそうですが。コツコツとやっていきましょう。

あ、本日、短いです。理由は明日知ると思いますが…

# 2. まずは解説
## 2.1 ifとunless

見慣れているifだけに一言。

https://elixirschool.com/ja/lessons/basics/control_structures#if-%E3%81%A8-unless-0
「Elixirでは偽とみなされる値は nil と真理値の false だけだということに、留意すべきです」

これ、if( value　)とかコード書いちゃうオレは注意な。
さて、ifはif～do～else～endで書くみたいですな。

```
if String.valid?("Hello") do
  "Valid string!"
else
  "Invalid string."
end
"Valid string!"
```
String.valid?("Hello")がtrueであれば、"Valid string!"を表示します。そうでなければ、"Invalid string."を。

```
if "a string value" do
  "Truthy"
end
"Truthy"
```

ちょっと面白いのが、これ、値を返してるだけなんですね。
実際のコーディングでは、こう言う使い方多そう。


# 2.2 unless

unlessは、「条件が否定される時だけ作用します」
```
unless is_integer("hello") do
  "Not an Int"
end
```
まー、ここでも、「Elixirでは偽とみなされる値は nil と真理値の false だけだということに、留意すべきです」ですね。


# 2.3 case

さて、Elixir Schoolを見てみましょう。

https://elixirschool.com/ja/lessons/basics/control_structures#case-1

複数のパターンに対してマッチする必要があるなら、 case/2 を使うことができます…

さて、ではやってみよう。
```
case {:ok, "Hello World"} do
  {:ok, result} -> result
  {:error} -> "Uh oh!"
  _ -> "Catch all"
end
"Hello World"
```

…素晴らしい。さて、今回のキモ

「変数は case/2 命令文の中に含まれる重要な要素です。これが無いと、マッチするものが見あたらない場合にエラーが発生します:」

```
case :even do
  :odd -> "Odd"
end
** (CaseClauseError) no case clause matching: :even
    (stdlib 6.0) erl_eval.erl:1272: :erl_eval.case_clauses/8
    #cell:a6cn227ei3bph5zz:1: (file)
```

…じゃぁ、なんにでもマッチするパターンを追加しましょうか。
```
iex(8)> case :even do
...(8)>   :odd -> "Odd"
...(8)>   _ -> "Not Odd"
...(8)> end
"Not Odd"
```
_ を追加することで、すべてのパターンにマッチする様になりました。

さて、最後に
「case/2 はパターンマッチに依存しているため、パターンマッチと同じルールや制限が全て適用されます。
　既存の変数に対してマッチさせようという場合にはピン ^ 演算子を使わなくてはいけません」

…これ、caseのマッチ対象側にも、変数使えるんですね。
```
iex(9)> pie = 3.14
3.14
iex(10)> case "cherry pie" do
...(10)>   ^pie -> "Not so tasty" ー＞こっちにはマッチしてない。
...(10)>   pie -> "I bet #{pie} is tasty"　<-この時点では、パターンマッチなので、pieには"cherry pie"が入る。
...(10)> end
"I bet cherry pie is tasty"
iex(13)> pie
3.14 <-この時点では、上のcase内部のcherryは捨てられ、元のpieが評価されている。
```
これ、caseが終わると、変数pieが、3.14に戻ってますね。
変数のScopeが原因だとは思いますが、これは後で解説する必要がありそうです。


すいませんが、サンプルにあるGuard句は、別途説明させてください。
本日はここらへんで

# 3. # 3. 本日のチートシート！
  |制御構造の名|説明|例|
  |:--------|:----------------------------------------|:------------------------------------------------------------------|
  |if|条件がtrueの時、do 以下の行を実行する|if String.valid?("Hello") do<br>  "Valid string!"<br>else<br>  "Invalid string."<br>end<br>"Valid string!"|
  |unless|条件がnilかfalseの時、do 以下の行の行を実行する|unless is_integer("hello") do<br>  "Not an Int"<br>end<br>|
  |case|do以降の行のパターンマッチを行い、->以降の行を実行する。|case {:ok, "Hello World"} do<br>  {:ok, result} -> result<br>  {:error} -> "Uh oh!"<br>  _ -> "Catch all"<br>end<br>"Hello World"<br>|

# 4. 本日の課題.…

僕の宿題をまとめておきます。

## 4.1 Expressions allowed in guard clausesを読もう
「この例は公式のElixirのGetting Startedガイドから直接持ってきています。
　公式ドキュメントからExpressions allowed in guard clausesを読んでみてください」

…guard構文らしいですね。
こんな話もあるので、後で調べて記事にしておきます。
https://qiita.com/FL4TLiN3/items/110d177175d6708322ca#%E3%81%82%E3%81%A8%E3%81%8C%E3%81%8D


## 4.2 変数のスコープと説明しよう





…