サブルーチン
命令群を使いまわす
これまで私たちは、Perl標準の関数を使って命令を書いてきました
たとえば print や chomp() などがそうです
これらの関数同様に、自分で記述した命令群をひとつの関数として登録することが可能です
この自作関数のことをサブルーチンと呼びます
逆に、サブルーチン以外の私たちがこれまで記述してきたコード部分をメインルーチンといいます
サブルーチンはメインルーチンの中で何度でも プログラムの再利用 が可能です
高度で長いプログラミングになると、この技術は必需です
サブルーチンの作成は、subステートメントを使い、名前と内容を記述します
sub sub_name {
statements
}
sub_nameには変数のように名前を付けます
こうして作成されたサブルーチンは、メインルーチンや他のサブルーチンの中で名前を呼べば内容を実行します
何度もプログラムの中で使用される処理や、あまりにも複雑で二度と作りたくないようなプログラムをサブルーチンにしておくと便利ですね
print "サブルーチンを呼び出します\n\n";
&my_sub;
print "\nもう一度再現します\n\n";
&my_sub;
sub my_sub {
print "ケロ 「さくらには無敵の呪文があるやないか」\n";
print "さくら「絶対、大丈夫だよ!」\n";
print "ともよ「その調子ですわ、さくらちゃん」\n"
}
サブルーチンを呼び出すには &サブルーチン名 です
&記号は省略可能してもエラーはでませんが、警告が出ますしサブルーチンが実行されないなどの問題が出ます(ActivePerl5)
&記号はサブルーチンを呼び出していることを明示的にするので忘れずに記述しましょう
サブルーチン内のステートメントを全て終了すると、プログラムは再び呼び出し元へ復帰し、次の命令から実行していきます
サブルーチンの呼び出しは、メインルーチン、他のサブルーチン、実行中のサブルーチン自身などからも呼び出せます
とくに長い命令になれば、サブルーチンにまとめるとメインルーチンの可読性があがります
用途に応じてサブルーチンを使い分けましょう
引数と戻り値
一連の命令をまとめたサブルーチンだけでは、呼び出しても同じ命令をくり返すだけでした
しかし、たとえば二つ数を加算した結果を出力するプログラムを作りたいとすれば
変化する情報をサブルーチンに渡す必要があります
この情報のことを引数と呼びます
引数はサブルーチンを呼び出すときに、サブルーチンに対して値や文字列を渡します
サブルーチン側では、渡された引数は特殊配列変数 _ に代入されます
引数は配列のリスト形式で渡されます、特殊配列変数は @_ で渡された全要素を参照できます
これは「配列」のリストでやったので、わかりやすいと思います
&sub_name(list1,listn...);
sub sub_name {
print @_;
print $_[n];
}
これで渡された引数リストを参照することができます
とにかく渡された引数はリストとして特殊配列変数 _ に代入されるということを覚えてください
&my_sub("引数1","引数2");
sub my_sub {
print "@_\n";
print $_[0];
}
この場合、@_ は渡された引数リストの全要素を参照します
$_[0]はスカラー変数なので、当然引数リストの0番目の要素を参照します(つまり「引数1」を)
このように、呼び出し側から情報を受け取ることによって動的なルーチンを作成できます
では、冒頭の「加算結果を出力」するプログラムを作りたいとします
この場合、サブルーチンの中でprint関数を使って出力しても問題はありませんが
printで出力するのではなく、変数に代入したいだけの場合などに制限を受けます
そこで、サブルーチンの中で引数を処理して、その結果を呼び出し元に返すことができれば便利ですね
この呼び出し元に返す値を戻り値といいます
戻り値はサブルーチンの最後の値が戻り値になります。これは変数や文字列もかまいません
print "戻り値 = ". &my_sub(5,6,1,89,4);
sub my_sub {
foreach $ary (@_) {
$ans += $ary;
}
$ans;
}
このプログラムでは、渡された引数リストをforeachステートメントを用いて全て$ansに加算します
その結果をサブルーチンの最後で $ans と変数だけをしていすることで、これを戻り値としています
しかし、他言語のプログラム経験者は気づくでしょうけど、これはあまり明示的ではありません
時が流れた後で再びソースを見ると、なにが戻り値なのかわからなくなったりするかもしれません
さらにサブルーチンの途中で何らかの条件によってルーチンを終わらせ戻り値を返したい場合はどうしましょう
このような場合はreturnステートメントを使用します
returnはサブルーチンの終わりを示します。そのためreturnを使うことによってどこがサブルーチンの終わりかを明示的にできます
return(value)
valueに戻り値を指定します
returnステートメントを実行した時点でプログラムはサブルーチンから抜け出して、呼び出し元に復帰します
print "戻り値 = ". &my_sub(5,6,1,89,4);
sub my_sub {
foreach $ary (@_) {
$ans += $ary;
return("加算結果が100を越えました") if ($ans >= 100);
}
return($ans);
}
returnステートメントで return() と記述した場合は空文字、または0が返されます
return(value)
サブルーチンを終了させ、呼び出し元に復帰します
valueには呼び出し元に返す戻り値を指定します