Perl 「 サブルーチン (Subroutine) 」: 定義と起動 (0x2f)

セラ (perlackline)

2013年10月29日 18:12



Perl について、復習を兼ねて断片的な情報を掲載して行く連載その 0x30 回。

Perl で、サブルーチン (Subroutine) を定義して、起動する。



サブルーチンとは



Perl では、予め組み込まれたシステム関数 (Function) (chomp, print 等) とは別に、サブルーチンと呼ばれるユーザ定義の関数を利用出来ます。

「 サブルーチン 」や「 関数 」の定義はプログラミング言語によって差異がある様ですが、少なくとも Perl では「 ユーザが定義した関数をサブルーチンと呼ぶ 」そうです。

関数とは、通常特定の処理をするためのひとかたまりのコード (特に引数を取るもの) を指すそうです。

特定の処理を行うコードのひとかたまりを定義しておけば、その定義を呼び出すだけで、該当する処理を繰り返し利用することが出来ます。

例えば、これまで使ってきた print 関数は標準出力への出力処理のコードがまとめてあります。また、chomp 関数は改行文字の削除処理のためのコードがまとめてあります。

Perl におけるサブルーチンは、ユーザが必要とするひとかたまりの処理を、ユーザ自らが定義するものと覚えておけばよさそうです。

サブルーチンの定義



Perl のサブルーチンは、次の様に定義します。


sub increment {
$n += 1;
print "Numbers increase by 1. -> $n\n"
}


サブルーチンは、「 sub 」を使って宣言します。

続く「 increment 」は、サブルーチンの名前です。この名前は「 Perl 識別子, 変数名 (0x09) 」で説明した、識別子のルールに従う限り任意の文字列を使えます。

配列変数の名前と同じく、サブルーチンの名前も独立した名前空間で管理されるため、同じプログラムの中にスカラ変数「 $increment 」が存在したとしても、Perl は問題にしません。

しかし、プログラムを保守する担当者 (や 3 ヶ月後のじぶん) のことを考えると、別の名前にしておいた方が無難だろうとのことです。

{ } 」ブロック内には、繰り返し利用したい処理を書きます。

ここでは、スカラ変数 $n に数値 1 を加える処理と、それから print 文で文字列を表示する処理が書かれています。

サブルーチンを定義する場所



サブルーチンの定義を書く場所は、通常プログラム内のどこでも構わない様です。

つまり、一番最初にまとめて書くことも、一番最後にまとめて書くことも、別のコードの合間に点在させることも可能です。

C 言語や Pascal といった言語に精通したプログラマは、ユーザ定義の関数をプログラムの先頭に書くことを好むそうですが、 僕の身近では、プログラムの最後にまとめているケースが多い様に思います。

また、サブルーチンは、よほど特別なことをしない限り、「 グローバル 」だといいます。

「 グローバル 」とは、簡単にいうと、プログラム内のどこからでも参照出来るということです。

反対に「 ローカル 」といった場合は、限られたスコープ内でしか参照出来ないことを意味します。

この辺の話は、「 レキシカル 」という用語とともに、別途説明する予定です。

グローバルなサブルーチンの中で、グローバルな変数を扱えてしまう Perl の仕様は、"言語純粋主義者" 達を震え上がらせる議論の的だった様ですが、Perl の開発者は、サブルーチン内でプライベート変数を定義するという方法で議論の駆逐に成功したそうです。

ちなみに、同じ名前のサブルーチンがひとつのプログラム内で定義されていた場合、後に書かれているものが優先される (前に書かれているものは後ろで書かれたものに上書き) ということを覚えておきましょう。

もちろんこの場合に (warnings プラグマ等で) 警告を有効にしておけば、Perl は注意を促すメッセージを表示します。

サブルーチン 起動 (Invoke)



サブルーチンの「 起動 (Invoke) 」は、多くの場合「 呼び出し (Call) 」と言われるそうです。

Perl では、サブルーチンの呼び出しに「 & (ampersand) 」を使います。「 アンパサンド 」、いわゆるアンド記号です。

「 & 」は、省略出来る場合と出来ない場合があるそうですが、基本的には (禁止されていない限り) 「 & 」を付けておいた方が安全だとのことです。

具体的には以下の様に呼び出します。



&increment; # Numbers increase by 1 -> 1
&increment; # Numbers increase by 1 -> 2
&increment; # Numbers increase by 1 -> 3

sub increment {
$n += 1;
print "Numbers increase by 1. -> $n\n"
}


5 行目で定義しているサブルーチン「 increment 」を、1 - 3 行目で呼び出しています。

サブルーチン「 increment 」の中にあるスカラ変数「 $n 」は、グローバルな変数なので、該当するサブルーチンが呼び出される毎に値が加算されます。

このとき、仮に「 $n 」がローカルな変数だった場合、その値は呼び出される毎に初期化 ( ? ) され、複数回呼び出しても値は加算されません。



&increment; # Numbers increase by 1 -> 1
&increment; # Numbers increase by 1 -> 1
&increment; # Numbers increase by 1 -> 1

sub increment {
my $n += 1; # my を使って $n をローカル変数にする
print "Numbers increase by 1. -> $n\n"
}


ローカル変数の宣言には、ここで利用した「 my 」の他に「 local 」という組み込み関数 (?) が使えます。このあたりの話はまた別の機会に行います。

0x2f -> 0x30 へ



サブルーチンの「 サブ 」は、メインルーチンの「 メイン 」に対するものです。

ルーチンは英語で「 Routine 」と書きますが、これは、「 決まった仕事 」や、「 慣例 」等を意味するそうです。

コンピュータの世界での「 Routine 」は、プログラムによる一連の作業を意味するとのことなので、「 メインルーチン 」は、プログラムの「 主要 」な作業を意味することになると思われます。

このことから、「 サブルーチン 」は「 副次的 」な作業を意味することが分かると思います。

参考情報は以下の書籍を中心に Wikipedia および各 Web サイト。それと詳しい先輩。

参考 :「Randal L. Schwartz, brian d foy, Tom Phoenix 共著 近藤 嘉雪 訳「初めての Perl 第 6 版」(オライリー・ジャパン発行 ISBN978-4-87311-567-2)」

次回 (0x30) へ続く。

過去記事 RSS









関連記事