§10.1 サブルーチンの宣言と呼び出し


作成日:2002/01/27(日)

この章では、サブルーチンについてお話します。 サブルーチンは、スクリプトを見やすくしたり、いくつもの場所で使う同じような操作を再利用可能にする、などの理由で用いられます。 この節では、サブルーチンの宣言と呼び出しの方法について紹介します。

サブルーチンを宣言する

まず、サブルーチンの宣言(定義)の方法です。 サブルーチンを定義するには、

 sub サブルーチン名 {
   実行文;
   実行文;
 }

のようにします。 サブルーチン名に使える文字は、変数名の場合と全く同じです。 また、変数や配列などと同じ名前を使っても、Perlはちゃんと別物として扱います。 では、簡単なサブルーチンの例をご紹介します。

 sub greeting {
   print "よっ、どう最近。\n";
 }

上のサブルーチンは、「よっ、どう最近。」と出力して改行するものです。 このように、まとめたい操作を{ }で囲んでやるだけでサブルーチンの出来あがりです。 サブルーチンは、スクリプトのどこにおいてもかまいませんが、スクリプトの最後に置くのが一般的のようです(僕もそうしています)。

サブルーチンを呼び出す

さて、作ったサブルーチンは早速使いましょう。 サブルーチンを使うには、次のようにしてサブルーチンを呼び出してやります。

 &greeting;

このように、サブルーチンを呼び出す際には、サブルーチン名の前に&(アンパーサンド)をつけます。 呼び出されたところで、定義済みのサブルーチンが実行されます。

引数を渡す

さて、上で作ったgreetingサブルーチンをちょっと改造して、名前を表示できるようにしましょう。 名前はキーボードから入力させる様にします。 まずはスクリプトを見てください。

 print "名前を入力してください。\n";
 $name = <STDIN>;
 chomp($name);
 
 greeting($name);

 sub greeting {
   print "よっ、$_[0]ちゃん、どう最近。\n";
 }

上のスクリプトを1行ずつ見ていきましょう。 まず1行目で「名前を入力してください。」と表示し、2行目で名前の入力を受け付けて、それを$name変数に格納します。 そして3行目でchomp関数を使って、最後の改行文字を除きます。 ここまではいいですか?

さて次。

 greeting($name);

とあります。 ここでgreetingサブルーチンを呼び出すと同時に、greetingサブルーチンに$nameという引数を渡しています。 この「引数」というのは、サブルーチンに渡すデータのことで、今の場合、「$nameの値を使って処理をしてくれ」と命令しているのです。 サブルーチンを引数つきで呼び出すときには上のように、引数を( )で囲みます。 複数の引数を渡すときには、それぞれをカンマで区切って書きます。 またサブルーチンに引数を渡す場合、先頭の&は省略することができます。

最後に、サブルーチンの定義部分を見てください。 print文の中に$_[0]という見なれない物が入っています。 サブルーチンに渡された引数は一度、@_という特殊配列に順にセットされます。 今の場合、greetingサブルーチンに渡された$nameの値が、@_にセットされたことになります。 ですからそれを参照するには、@_配列の最初の要素と言う意味で$_[0]と書くのです。

サブルーチンの中で、また別のサブルーチンを呼び出すことも出来ます。 この場合も、引数は1度@_配列に保存されますが、今持っている@_の値が消えてしまわないように、いったん別の場所に保存され、呼び出したサブルーチンの処理が終わって最初のサブルーチンに戻ってきたときに自動的に@_配列の値も、もとへもどります。

 sub1("最初のサブルーチン");

 sub sub1{
   print "ここは、$_[0]\n";
   #$_[0]は"最初のサブルーチン"

   $second_param = "次のサブルーチン";
   sub2($second_param);
   #$_[0]は"次のサブルーチン"

   print "ここは、$_[0]\n";
   #$_[0]は"最初のサブルーチン"
 }

この節では、サブルーチンの宣言と呼び出し方法について紹介してきました。 次の節では、変数の局所化についてお話します。


「§9.1 ディレクトリの操作」へ 「§10.2 変数の局所化」へ
ソフトバンク パブリッシング株式会社

Copyright (C) can All Rights Reserved
e-mail:ishiki@mrj.biglobe.ne.jp