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を見てみましょう。
複数のパターンに対してマッチする必要があるなら、 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 "Valid string!" else "Invalid string." end "Valid string!" |
unless | 条件がnilかfalseの時、do 以下の行の行を実行する | unless is_integer("hello") do "Not an Int" end |
case | do以降の行のパターンマッチを行い、->以降の行を実行する。 | case {:ok, "Hello World"} do {:ok, result} -> result {:error} -> "Uh oh!" _ -> "Catch all" end "Hello World" |
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 変数のスコープと説明しよう
…