サブルーチン(subroutine)
perlには、たくさんの関数があります。関数とは、ひとかたまりの処理の集まりで、繰り返し呼び出すことのできるプログラムの部品(モジュール)です。
ここまででも、すでにprintなどいくつかの関数が出てきていますが、このプログラムの部品はユーザー自身が作成することもできます。
これを、ユーザー定義関数(ユーザー関数)、あるいはサブルーチン(subroutine)といいます。
サブルーチンは、 好きな場所に記述することができます。その、名前はスカラー変数などと同じルールにのっとって付けられ、独自に管理されるため変数と同じ名前を付けることができます。
ただし、同じサブルーチン名を使用したときは、後に定義されたブルーチンで上書きされます。
サブルーチンは以下のような、形式により定義されます。
sub subname { statement_1 ; statement_2 ; statement_3 ; }
まず最初に、サブルーチンを定義するためのキーワードsubを入れます。次にサブルーチンの名前(subname)、最後にサブルーチンで行う処理を、ブレースで囲み記述します。
また、ブレース内は通常のプログラムと同様に記述され、グローバル変数が使用できますが、関数内だけで使用されるローカル変数も定義することが出来ます。 (後述)
サブルーチン呼び出し(subroutine)
サブルーチンを呼び出すには、サブルーチン名の先頭に&、後ろに( )を付け、「& subname ()」としてプログラム中のどこからでも呼び出すことが出来ます。ただし、( )や&は省略して 「subname ()」、「& subname」、とする記述も可能です。
サブルーチンの中で別のサブルーチンを呼び出すこともできますし、自分と同じサブルーチンを呼び出すことも出来ます。ただし、そのような記述は適宜サブルーチンから抜け出すようにしておかないと、無限ループに陥ってしまいますのでご注意を。
戻り値(return value)
サブルーチンは演算子や組み込み関数と同様、呼び出しによって得られることで値を得ることが出来ます。
通常は、サブルーチン内でreturn文によって明示的に指定しますが、そうでなかった場合は、サブルーチン内で最後に評価された式の値が自動的に戻り値となります。(最後に書かれている式ではありません)
次のような場合、「typing」という関数は呼び出された時点で「50」という値を持ち、$cは「50」です。その関数の戻り値を利用して式を組み立てた場合、$dは25になります。
sub typing { return $a + $b ; } $a = 5 ; $b = 10 ; $c = typing ( ) ; $d = typing ( ) / 2;
また、return文で戻り値にリストコンテキストを設定した場合や、リストを返す演算子や関数を指定した場合は戻り値がリストになります。
引数(argument)
サブルーチンは単純に呼び出すだけでなく、引数(ひきすう)を渡すことにより、状況にあった様々な処理を行うことが出来ます。
サブルーチンに引数を渡すときは、サブルーチンを呼び出すときに後ろの()内に値をセットします。渡したい値が複数ある場合は「,」で区切ります。
サブルーチンは受け取った引数のリストを特別な配列変数「@_ 」に格納します(引数が一つの場合は、標準変数「$_」で呼び出すことが出来ます )。サブルーチン内でこの配列変数にアクセスすれば、引数の個数や各引数の値を知ることができます。
グローバル変数、ローカル変数
しかし、この「@_ 」は別のサブルーチンも同じように使用しています。
あるいは、サブルーチン外の別の場所で使っていることがあるかもしれません。しかし、サブルーチン内で使われる「@_ 」は、常にサブルーチン内だけで有効で他の「@_ 」と干渉はしません。
aというサブルーチンが、その内部で$_[0]を100に設定したとして、bというサブルーチンではそれを利用することは出来ません。bではまったく新規で「@_ 」という変数が用意されます。
これまで、使用してきたような、どこでも同じように使える変数を「グローバル変数」、特定のサブルーチンの中だけで使用され他と干渉しない変数を「ローカル変数」といいます。
配列変数「@ 」へのアクセス
sub color_select { print "select color $_[0]"; } &color_select("red");#1 $a = "bule"; &color_select($a);#2
上のソースでは#1ではselect color red”と表示し、#2では”select color bule”と表示します。
サブルーチン内での、引数の配列変数に対するアクセスは、通常の配列に対するものとまったく同じになります。
つまり、渡されたパラメータが不足していて、アクセスした場合はundefを返し、多すぎる引数を渡した場合は、余分な部分はまったく無視されて捨てられます。
sub appearance_color { print "It's a $_[0] $_[1]"; } &appearance_color("Deep","red");#1 $a = "Bright"; $b = "bule"; &appearance_color($a,$b);#2 &appearance_color("Green");#3
この例では#1では”It's a Deep red”、#2では”It's a Bright bule”、#3では”It's a Greenと表示されます。
ローカル変数(インスタンシエーション(instantiation)) - my 演算子
サブルーチンを起動するとローカル変数 @_ が作成されますが、my演算子を使うと同じ働きをする変数を作成することができます。
作成される変数は、他に同じ名前のグローバル変数が存在していてもお互いに干渉しません。
サブルーチンの外と中で同じ変数を使いたい場合や、プログラムが大きくなって変数のバリエーションが無い場合、複数の人間が一つのプログラムにかかわる場合など、変数をローカル化することで、変数の衝突を防ぐことが出来ます。
次の例では、グローバル変数の$sumとローカル変数の$sumが同時に使われていますが、ローカル変数の$sumによってグローバル変数の$sumが0に戻ることは起こりません。
$sum = 0; $sum += &total_value(1,10); $sum += &total_value(10,100); print "ALL Sum $sum .\n"; sub total_value { my ( $sum) ; #1 my ( $from) ;#1 my ( $to) ; #1 $sum = 0 ; #2 $from = $_[0];#2 $to = $_[1];#2 for ( $i = $from; $i <= $to ; $i++ ) { $sum += $i ; } print "This total $sum .\n"; return $sum ; }
また、#の部分は、「my ( $sum,$from,$to) 」などとまとめて書くことが出来るほか、#1と#2をまとめて、
my ($sum) = 0 ; my ($from) = $_[0]; my ($to) = $_[1];
などと書くことも可能です。
また、特殊変数の@_を次のように、別の配列にコピーして使うことや、$_[0]と$_[1]以降を切り分けて使うなど、通常の配列の代入で使用できる方法をそのまま使うことが出来ます。
my ( @values ) = @_ ; my ( $n , @values ) = @_ ;
local 演算子
local演算子は、my演算子と同じく局所的に有効な変数(「プライベート」な変数)を作ることができます。
ただし、local の場合はその宣言が行われたブロックから呼び出された関数からも変数を参照することができます。
また、$_、$1、$ARGV などの組み込み変数はは my宣言することはできませんが、localで宣言することは可能です。
実は、local変数は有効範囲を限定したグローバル変数です。
実行速度から見ても、安全性の面から見ても、できるだけlocalよりmyを使うべきです。
(my演算子は、Perl 5 以降使えるようになっています)
strictプラグマ(pragma)
strictプラグマ(pragma)をファイルの先頭に記述すると、「my」で宣言してからしか変数を使用することが出来なくなります。
「use」は、外部のモジュールを使うための命令です。モジュール名を指定すると、そのモジュールを呼び出しますが、モジュール名が小文字だけのものを特に「プラグマ・モジュール」または「プラグマ」と呼びます。
プラグマはコンパイル命令です。ですから、staticのルールに反すると、コンパイル時点でエラーになってしまいます。
strictプラグマは、宣言していない変数の禁止のほかに、ベアワード(引用符で囲まれていない裸の単語。状況により文字列や関数に解釈されてしまう)やシンボリック・リファレンス(文字列によるリファレンス)を使うことを禁じます。
use strict ; my @aquarium = qw (shark octopus tuna) ; my $fish = "seaweed"; push ( @aquarium , $fish ) ; @list = sort @aquarium ; print @list;
上の例で言えば、@listは宣言されていないのでエラーになります。
それではと、$fishの宣言の後に次の宣言を入れて見ます。
my @lists;
これもエラーになります。なぜなら@listを@listsとタイプミスしているからです。
次のようにすることでエラーはなくなります。
my @list;
strictプラグマにより変数宣言を強制することにより、コーディング時のタイプミスも早期に発見することができ、プログラムが変数にアクセスする時の実行速度が高速になります。
そのため、出来る限りstrictプラグマを使用してプログラミングをするのが望ましいとされています。
ポイント
- サブルーチンを定義するためのキーワードsubを使用する。
- サブルーチンを呼び出すときは、名前の先頭に&、後ろに( )を付ける。
(()には引数を入れる) - 引数のリストを特別な配列変数「@_ 」に格納される。
- strictプラグマ、my演算子を使用してプログラミングをするのが望ましい。
Proces | Study of CGI | I/O |
□新着
- 2016/04/14
ページ復旧 - 2007/10/06
Story Maker始動 - 2007/06/13
久々の更新 - 2007/01/06
logちょっとバージョンアップ - 2006/07/27
ホームページのPerl 終了
□Topics
- 2016/04/14
サイト復旧 - 2007/10/06
StoryMaker始動 - 2007/06/13
今後にぜひご期待を! - 2006/06/26
今後について - 2006/06/15
環境の変化