関数定義(3) 返り値を返す

次に、返り値を返してみます。
返り値は return で返せるらしいです。引数の渡し方とはうってかわって、こちらはおなじみですね。(^_^;
以下、「perldoc -f return」の引用です。

return EXPR
return  Returns from a subroutine, "eval", or "do FILE" with the value
        given in EXPR. Evaluation of EXPR may be in list, scalar, or
        void context, depending on how the return value will be used,
        and the context may vary from one execution to the next (see
        "wantarray"). If no EXPR is given, returns an empty list in list
        context, the undefined value in scalar context, and (of course)
        nothing at all in a void context.

EXPR で指定した値を返す。EXPR は、返り値がどのように使われるかによって、リストコンテキスト、スカラーコンテキスト、ヴォイドコンテキストのどれかとして評価される、と書いてありますね。
コンテキストとは「文脈」の事ですが、Perl では文脈によって同じ表現が違う意味になる、というのは以前の日記でも出てきました。
例えば @array と書いた時も、リストコンテキスト(リスト値が必要な文脈)の場合はそのままリストとして扱われ、スカラーコンテキスト(スカラー値が必要な文脈)の場合はリストの要素数として扱われるのでした。
EXPR を指定しない場合も同じように、リストコンテキストでは空のリストが、スカラーコンテキストでは「未定義(undef)」という値が返され、そしてヴォイドコンテキスト(関数の副作用だけが目当てで返り値は使われない場合)ではもちろん何も返さない、となっています。
英文でも文脈によって同じ単語が動詞だったり名詞だったりするので、英語圏で生まれたプログラミング言語ならではだと思いますが、ちょっと難しいですね。(^_^;)
とりあえず、難しい事は考えずにスカラー値を返してみます。

# add.pl
 
sub add {
	my ($left, $right) = @_;
	return $left + $right;
}
 
print add(10, 5), "\n";
print add(40, 50), "\n";
print add(22, 33), "\n";

add 関数は2つの数字を受け取って、それらを加算した数字を返します。
引数の受け取り方ですが、my ($left, $right) = @_; と書くと、1番目の引数が $left に、2番目の引数が $right に代入されます。複数の変数をカッコで囲むとリストとして評価されるので、これはリストに代入している事になります。リストに代入する場合、左辺に置くリストに含まれる要素は全て代入可能である必要があるとの事。(第三版「プログラミングPerl VOL.1」p.88)
以下、実行結果です。

15
90
55

ちゃんと足し算した結果が出ていますね。(^_^)
ではでは、今度は「いくつかの数字を受け取ってそれらを合計した数字を返す sum 関数」を作ってみたいと思います。
「いくつかの」という事は、1つでも2つでも3つでも、何個でも受け取れる、という事です。

# sum.pl
 
sub sum {
	my $sum = 0;
	foreach(@_) { $sum += $_; }
	return $sum;
}
 
print sum(1, 2), "\n";
print sum(10, 15, 20, 25), "\n";
 
my @arr = (2, 2, 2, 2, 2);
print sum(@arr), "\n";

書いてみました。foreach を使えば配列の各要素に対して繰り返しブロックを実行できるんでしたね。
ここでは、引数の配列である @_ の各要素を $sum に足していっています。そして、最終的に $sum を返すので、引数の総和が得られました。
また、呼び出す際に配列を渡しています。引数はリストコンテキストで評価されるので、配列の内容が展開されるはずです。
実行結果です。

3
70
10

うまくいきました。(^_^)
少しずつ、Perlの関数がわかってきた気がします。「コンテキスト」という考え方は慣れないと難しいですが、慣れてくるとソースコードを簡潔に書く事ができて面白いですね。