Perl Perl_0
Perl 引数のリストを「 可変長 」として扱う(0x34)

目次 - Perl Index
Theme
Perl について、復習を兼ねて断片的な情報を掲載して行く連載その 0x34 回。
Perl のサブルーチンに、引数として渡すリスト (パラメータリスト) を可変長として扱う。
可変長とは
「 可変長 」とは、「 長さ 」が「 可変 」という意味です。英語では「 Variable length 」と言うそうです。
反対に、「 長さ 」が「 固定 」されているものを「 固定長 」と呼びます。英語では「 Fixed length 」と言うそうです。
固定長のパラメータリスト
まず、Perl のサブルーチンで、パラメータリストが固定長の場合を確認します。
しかしながら、Perl では、通常厳格な固定長のパラメータリストを設定する機能を持っていません。Perl におけるパラメータリストは標準で可変長です。
これは、他の多くのプログラミング言語に比べてユニークな事実だと言います。
Perl ではない多くのプログラミング言語では、サブルーチンを定義する時点で、厳格にその長さ (個数)、型を指定する必要があるからです。
パラメータリストが標準で可変長なのは、Perl の「 不要な制限を導入しない 」という哲学からくる処置ですが、もちろん、「 固定長の様に 」プログラムを書くことは可能です。
パラメータリストを 2 つに限定したい場合は、例えば次の様にします。
sub mysub {
if ( @_ != 2 ) {
print "Please get exactly two arguments for subroutine.
# パラメータが 2 つでない場合の処理
}
# パラメータが 2 つの場合の処理
:
.
2 行目の if 文で配列「 @_ 」の要素の個数が 2 つであるかどうかを確認しています。
ここでは、配列変数がスカラコンテキストで使われた場合に個数を返す機能を利用して、パラメータリストの個数チェックを行っています。
しかしながら、通常 Perl プログラミングでは、わざわざこの様な方法は行いません。なぜなら、パラメータリストがいくつあっても良い様にサブルーチンを適応させる方が好ましい手段だからです。
可変長のパラメータリストに対応する
「 Perl 「 サブルーチン (Subroutine) 」: 引数 (0x31) 」で確認した以下のサブルーチンは、2 つの引数を取って、大きな方の値を返すコードでした。
つまり、 パラメータリストの値は 2 つに固定されています。
sub compare {
if ( $_[0] > $_[1] {
$_[0];
} else {
$_[1];
}
このサブルーチンの中で扱える値は、配列「 @_ 」の要素「 $_[0] 」と「 $_[1] 」の 2 つだけなので、 パラメータリストの3 つめ以降の値は破棄されます。
しかしながら、ユーザの希望が「 10 個の値を比較したい 」というものだった場合に、「 比較出来るのは始めの 2 つだけです 」と断るのは面白くありません。
ですから、パラメータリストがいくつ来ても良い様に、サブルーチンを改修します。
$maximum = &max(3, 5, 10, 4, 6);
sub max {
my ( $max_so_far ) = shift @_;
foreach ( @_ ) {
if ( $_ > $max_so_far ) {
$max_so_far = $_;
}
}
$max_so_far;
}
これは、「 初めての Perl 第 6 版 (P.85) 」で紹介されている「 最高水位線 (high-water mark) 」というアルゴリズムです。
サブルーチン max の中身を見てみましょう。
まず、 4 行目でレキシカル変数 「 $max_so_far 」を宣言し、配列「 @_ 」から shift 演算子で得た値を代入しています。
「 Perl pop & push に対する「 shift & unshift 演算子 」 (0x23) 」で確認した通り、shift 演算子は配列の先頭の値を取り出すので、この時点で $max_so_far の値 (初期値) は「 3 」になります。
次に、foreach 文に @_ をセットして、配列の要素の値を 1 つずつ取り出します。
foreach 文の中の if 文では、制御変数 (デフォルトの) $_ にセットされた値が、その時点の $max_so_far より大きいかどうかを評価しています。
ここでは、最終的により大きい値を得たいと考えているので、$_ の値がより大きい場合には、$max_so_far に代入し値を入れ替えます。
これを、配列の終わりまで繰り返せば、$max_so_far に最後まで残った値が最も大きな値になります。このため 11行目で戻り値として返される変数 $max_so_far にはパラメータリストの最大値が格納されています。
もし仮に、パラメータリストが空だったとしても特に問題はありません。その場合は戻り値が「 undef 」になるだけです。
ただし、戻り値が「 undef 」では困る場合は、当然なんらかの処理を加える必要があります。
0x34 -> 0x35 へ
今回は、「 最高水位線 (high-water mark) 」というアルゴリズムを紹介しました。
アルゴリズム ( Algorithm ) は「 算法 」ともいわれ、「 問題を解くための一連の手順 」を意味します。
プログラミング言語によるプログラムは、特定の問題を解くための手順をコンピュータに指示するためのアルゴリズムそのものなのだそうです。
世界には数多くの問題がありますが、それらの問題を解く方法は必ずしもひとつに限られている訳ではありません。
例えば、「 雨が降っている 」場合に「 雨に濡れない様にする 」ためには「 傘をさす 」方法もあれば、「 雨合羽を羽織る 」方法もあります。「 雨に濡れない 」事だけを考えるなら、「 家から出ない 」という方法もあります。
似た様な問題であっても、その目的が異なる場合は、それぞれ最適なアルゴリズムは変わってくるということです。
ある問題に対するアルゴリズムを、すべてじぶんで考え出すのも一興ですが、多くの先輩が遺した有用なアルゴリズムを学ぶことも忘れない様にしたいですね。
"Done is better than perfect"
参考情報は書籍「 初めての Perl 第 6 版 」を中心に perldoc, Wikipedia および各 Web サイト。それと詳しい先輩。
目次 - Perl Index
Perl mp2 翻訳 Web コンテンツ圧縮の FAQ (d228)
Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227)
Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226)
Perl mp2 翻訳 テンプレートシステムの選択 (d225)
Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224)
Perl mp2 翻訳 チュートリアル (d223)
Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227)
Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226)
Perl mp2 翻訳 テンプレートシステムの選択 (d225)
Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224)
Perl mp2 翻訳 チュートリアル (d223)