Elixirは、関数に複数の節を持たせることで、開放閉鎖原則の実践をしやすくしています。制御ロジックをあちこちに散らかしてハードコードするのではなく、的を絞った関数を書けば、振る舞いを簡単に追加したり削除したりできるのです。
Elixirには、次のように書くための_複数の関数節_と_ガード_があります。
def number(n) when n == 7 do
"Awesome, that's my favorite"
end
def number(_n) do
"That's not my favorite"
end
実行時、Elixirはソースファイルの上から下に向かって、どの関数節を呼び出すかを調べます。
使われていない変数には、先頭にアンダースコアを付けます。
ガードは、ガード関数による引数の評価に基づいて、Elixirが関数を呼び出すのを防ぐために使われます。ガードはwhenキーワードで始まり、その後に真偽値の式が続きます。ガード関数は、次の条件を満たす特別な関数です。
trueまたはfalseの値を返すこと。よく使われるガードの一覧は、Elixirのドキュメントにあります。これには、型チェック、基本的な算術、比較、厳密な真偽値演算子が含まれます。
関数は、1つ以上の引数にデフォルト値を宣言できます。次の関数を見てみましょう。
def number(n \\ 13), do: "That's not my favorite"
コンパイルすると、Elixirはnumber/0(引数なし)とnumber/1(引数1つ)の関数定義を作成します。
複数の引数にデフォルト値がある場合、デフォルト値は左から右へと関数に適用され、足りない引数を埋めます。
関数に複数の節がある場合、デフォルト引数は、関数節の前にある関数ヘッダー(本体のない関数)で定義します。
def number(n \\ 13)
def number(n) when n < 10, do: "Dream bigger!"
def number(n) when n > 100, do: "Not that big..."
友達が秘密の数値を当てる、ちょっとしたオンラインゲームを作っているとします。いくつかフィードバックを返したいものの、1回の予想で答えを明かすわけにはいきません。そこで、予想と秘密の数値の関係に応じて、違う応答を返す関数を考える必要があります。
| 条件 | 応答 |
|---|---|
| 予想が秘密の数値と一致するとき | "Correct" |
| 予想が秘密の数値より1つ大きいか1つ小さいとき | "So close" |
| 予想が秘密の数値より大きいとき | "Too high" |
| 予想が秘密の数値より小さいとき | "Too low" |
| 予想がされていないとき | "Make a guess" |
予想と秘密の数値は、すべて整数です。
2つの引数secret_numberとguess(どちらも整数)を取るcompare/2関数を実装します。
GuessingGame.compare(5, 5)
# => "Correct"
秘密の数値より大きい予想に応答するように、compare関数を変更します。
GuessingGame.compare(5, 8)
# => "Too high"
秘密の数値より小さい予想に応答するように、compare関数を変更します。
GuessingGame.compare(5, 2)
# => "Too low"
秘密の数値に近い予想に応答するように、compare関数を変更します。
GuessingGame.compare(5, 6)
# => "So close"
GuessingGame.compare(5, 4)
# => "So close"
予想がない場合に応答するように、compare関数を変更します。
GuessingGame.compare(5)
# => "Make a guess"
GuessingGame.compare(5, :no_guess)
# => "Make a guess"