2008-07-05
サブルーチンへのリファレンスを利用したポリモーフィズム
サブルーチンへのリファレンスを利用したポリモーフィズムを実現したサンプルです。
use strict; use warnings; my @nums = (1, 2, 3); print "1: サブルーチンへのリファレンスを使って合計と平均を順番に求める。\n"; # サブルーチンへのリファレンスの# 配列を作成。 my @calc_funcs = (\&sum, \&average); for my $calc_func (@calc_funcs) { my $result = $calc_func->(@nums); print "結果: $result\n"; } print "\n"; sub sum { my @nums = @_; my $total; for my $num (@nums) { $total += $num; } return $total; } sub average { return sum(@_) / @_; } print "2: サブルーチンへのリファレンスを使って選択的に処理する。\n"; my $how_to_calc = 'sum'; my $calc_func; if ($how_to_calc eq 'sum') { $calc_func = \∑ } else { $calc_func = \&average; } my $result = $calc_func->(@nums); print "計算方法 : $how_to_calc\n" . "結果 : $result\n\n"; print "3: サブルーチンへのリファレンスとハッシュを使って選択的に処理する。\n"; $how_to_calc = 'average'; my %calc_table = (sum => \&sum, average => \&average); # $calc_table{'average'} には、サブルーチンへのリファレンス # が入っているので、-> 演算子でデリファレンスして # サブルーチンを呼び出す。 $result = $calc_table{ $how_to_calc }->(@nums); print "計算方法 : $how_to_calc\n" . "結果 : $result\n\n";
変数に対してサブルーチンを順番に適用する
my @calc_funcs = (\&sum, \&average); for my $calc_func (@calc_funcs) { my $result = $calc_func->(@nums); }
ある変数に対してサブルーチンを順番に適用するには、サブルーチンへのリファレンスを利用します。サブルーチンへのリファレンスを配列に格納して、forループで繰り返しサブルーチンを呼び出します。
変数とサブルーチンのイメージ
|----------| | |<-------- サブルーチン1 | | | 変数 |<-------- サブルーチン2 | | | |<-------- サブルーチン3 |----------|
ある種類の引数に対して、順番にサブルーチンを適用していくイメージ。引数は固定で、サブルーチンが移り変わってゆくイメージ。
サブルーチンへのリファレンスを利用したポリモーフィズム
# if文で分岐する方法 my $how_to_calc = 'sum'; my $calc_func; if ($how_to_calc eq 'sum') { $calc_func = \∑ } else { $calc_func = \&average; } my $result = $calc_func->(@nums);
ポリモーフィズムとは、「同じ記述であるのに異なる関数が呼び出される」ということを意味する言葉です。オブジェクト指向では、「オブジェクトに応じて異なるメソッドが適用される」ということを意味する場合が多いです。
この例の場合は、 $calc_func->(@num) という記述は、$calc_func に何が代入されているかによって意味を変えます。\$sum が代入されている場合は、sum サブルーチンが呼びだされ、\$average が代入されている場合は、average サブルーチンが呼びだされます。
javaでは、オーバーロードとオーバーライドがポリモーフィズムを実現するための方法で、C言語では関数ポインタです。
ハッシュを利用した美しい方法
$how_to_calc = 'average'; my %calc_table = (sum => \&sum, average => \&average); $result = $calc_table{$how_to_calc}->(@nums);
この使用方法が関数リファレンスによるポリモーフィズムのもっとも洗練された形だとわたしは思っています。
選択的な処理であるのに、if文をいっさい使っていません。ハッシュのキーに対応したサブルーチンを呼ぶことで、処理を分岐させています。
トラックバック - http://d.hatena.ne.jp/perlcodesample/20080705/1215274675
リンク元
- 63 http://www.google.co.jp/search?hl=ja&q=ポリモーフィズム&btnG=Google+検索&lr=
- 57 https://www.google.co.jp/
- 53 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&q=Perl++sub&btnG=検索&lr=lang_ja
- 48 http://www.perlcodesample.com/perltut/tocsimple.html
- 35 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GGIH_jaJP242JP242&q=perl+配列 入れ子
- 25 http://www.google.co.jp/search?q=ポリモーフィズム&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a
- 24 http://www.google.co.jp/search?q=Perl+サブルーチン リファレンス&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a
- 24 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CDQQFjAB&url=http://d.hatena.ne.jp/perlcodesample/20080705/1215274675&ei=L64lUdT9JqrkmAX524DwCQ&usg=AFQjCNFgt2n7helN9S0lDycX-MIK7xgbJQ&bvm=bv.42661473,d.dGY
- 23 http://www.google.co.jp/search?hl=ja&q=perl+サブルーチン リファレンス 引数&lr=
- 18 http://www.google.co.jp/search?q=perl+リファレンス+配列の個数&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a