前提条件:learn-code-basics-5-writing-reusable-code-in-verse
「レッスン 5 」で、関数 は、アクションを実行したり入力に基づいて出力を作成したりするための命令を与える 再利用可能なコード であることを学びました。
関数を定義するには、一意の識別子、関数の結果として想定される情報の 型、関数が呼び出されたときに 何を行うか、という 3 つの重要な部分が必要です。
関数を定義する方法
関数シグネチャ
「レッスン 3」では、名前を付け、使用する値の型を与えることによって、変数や定数を 宣言 する方法について学びました。
関数シグネチャ はそれと同じように機能します。関数シグネチャでは、関数の一意の 識別子 を使用し、必要とする入力を記述する パラメータ、そして結果、つまり出力の 戻り値の型 も使用します。

関数が実際に行うことは、コード ブロック 内で定義されています。
コード ブロック
コード ブロック は、関数シグネチャの後に続く 式 のグループのことです。関数とそのコード ブロックの構文を次に示しています。
name() : type =
code block (コード ブロック)
コード ブロックの書式にはいくつかの方法があります。 一つの方法は、識別子の後にコードの行をインデントすることです。 上記の関数の構文ではそうなっています (コード ブロックをセットアップする方法の詳細については後で学びますが、今はこの書式を使います)。
コード ブロック内の式では、その関数が呼び出されたときに実際に何を行うかを定義します。
これらの式は、その関数が呼び出されたときにのみ実行されます。 プログラムがコード ブロックの終わりに達すると、これらの式は完了し (少なくとも、その関数が次回呼び出されるまで)、プログラムは、その関数呼び出しの後に続くコードを実行します。

本体
関数が何を行うかを定義しているコード ブロックは 本体 とも呼ばれます。
スコープ
ここまでで、以下のことを学びました。
- 関数には、プログラム内で何かを行うためにそれをアクティブ化するために使用される一意の識別子がある。
- 関数が行うことは、関数本体にある式に基づいている。
- 本体にあるコードの最終行が実行されると、その関数呼び出しは完了し、プログラムはプログラム内でその関数呼び出しの後に続く行のコードに進む。
関数内にある命令およびその関数から生じる値によって、関数の スコープ が決まります。
そろそろ、関数の定義に使用できる式に戻ります。定数や変数 (「レッスン 3 」で学んだ) を作成し、それらを関数本体に追加できます。
変数を本体内に置いた場合、その変数はその関数のスコープに ローカル になります。ここで言う ローカル は、このコードがその本体内でのみ、そしてその関数が呼び出されているときにのみ、存在および動作することを意味します。
それでは、スコープ とは何でしょうか?関数名の、その関数によって生み出される値への関連付け のことです。その値を使用できるのは、それが作成されているコード ブロック内、つまりそのスコープ内のみです。
インスタンス化
インスタンス とは、関数が呼び出されて実行される場合の、その関数の一意の適用のことです。インスタンスの作成が インスタンス化 です。インスタンスとインスタンス化はどちらも、非常に短い時間を表す instant という単語に関連があります。
そして、これによって 存続期間 という概念が提起されます。
存続期間
インスタンスには 存続期間 があります。つまり、始まりがあって、途中があり、終わりがあります。
したがって、関数本体内にあるものの 存続期間 は本体の スコープ に限定されていて、そのスコープ外ではそのローカル変数 (現在のスコープに限定されている変数) にアクセスすることはできません。
条件式
次の例は、プレイヤーが所持しているコインの数で購入できるネズミ捕り器の最大数を計算する方法を示しています。
定数 MousetrapsYouCanBuy
は if
ブロック内で作成されているため、そのスコープはその if
ブロックに限定されています。
この定数 MaxMousetrapsYouCanBuy
をその if
のコード ブロックの外側で使用すると、そのスコープの外側には MaxMousetrapsYouCanBuy
という名前は存在しないためエラーになり、「Unknown Identifier」というメッセージが表示されます。これは、MaxMousetrapsYouCanBuy
がそのスコープ内でのみ有効であることを意味しています。

式が完了すると、その本体内で作成されたローカル定数とローカル変数は存在しなくなります。 それらは存続期間の終了に達したからです。
スコープ は、完了するまで動作するコードの小さな塊と考えることができます。
関数の構文
関数の構文についてもう一度見ていきますが、今度はもう少し詳しく説明します。
name() : type =
code block (コード ブロック)
name() : type = |
これは 関数シグネチャ です。 関数シグネチャには、使用される入力の 型 が含まれています。 関数が返す 値 ( |
codeblock |
関数のコード ブロック、つまり 本体 には、定数、変数、および 関数が呼び出されたときに行う ことを表す式を追加します。 |
たとえば、ネズミ捕り器の代金を支払うための関数は次のようになります。
var Coins : int = 500
CoinsPerMousetrap : int = 100
BuyMousetrap() : void =
set Coins = Coins - CoinsPerMousetrap
Print("Mousetrap bought!You have {Coins} coins left.")
関数名の 命名規則とルール は、変数名や定数名に使用したものと同じです。関数は一連のアクションを行うため、BuyMousetrap()
のように、行うアクションを表す名前を付けることをお勧めします。
void
BuyMousetrap()
の関数シグネチャにある void
にお気付きかもしれません。関数の void 型は、その関数呼び出しが何も返さないことを意味します。「void」とは何かおよびその使用方法については、次のレッスンで学びます。
繰り返しを避ける
プログラミングでの重要な原則は 繰り返しを避けること (DRY:Don't Repeat Yourself) です。
これは、同じコード行を 3 回以上繰り返しているなら、別のやり方で記述することを検討すべきであるという意味です。 もちろん、これには理由があります。
記述するコード行が多くなるほど、そのコードを維持するのが困難になり、バグの原因になる可能性が高くなるからです。たとえば、ある場所でやむを得ずコードを変えたのに他の場所では変更していないと、バグになります。
関数は、定数と同様に、コードの不要な繰り返しを避ける 1 つの手段であるため、関数を使うと、コードの重複を防ぐだけでなくメンテナンスも軽減され、コードのエラーの可能性も低くなります。
式や関数に名前を付ける場合と、キーワードや組み込み関数を使う場合のどちらでも、コードを記述するときに大文字の使用には注意を払ってください。 Verse では、大文字と小文字が区別されるため、適切で一貫性のある大文字の使用に誤りがあると、バグやコンパイル エラーの原因になります。
まとめ
- 関数 は、アクションを実行したり入力に基づいて出力を作成したりするための命令を与える、再利用可能なコードです。
- 関数には、識別子、型、そして 関数が呼び出されたときにどのような結果になるか が入っている コード ブロック、という 3 つの部分が必要です。
- 関数は、その 関数シグネチャ を使用して呼び出されます。
- 関数が何を行うかを定義しているコード ブロックは本体とも呼ばれます。
- スコープ は、関数と関連付けられている値のことであり、コード ブロックのコンテンツによって定義されます。
- コード ブロックに入っているコードは、そのスコープに ローカル です。
- 存続期間 は、スコープの期間のことです。
- 繰り返しを避けましょう。