エイリアスメソッドの作成方法
ここにhogeというメソッドがあるとして
sub hoge { my $self = shift; my $num = shift; return $num + 10; }
こいつと同じ動きをするhoge_aliasメソッドを作成する場合、
例えば下記のようにhogeメソッドにそのまま投げるやり方がすぐ思いつく方法かな。
sub hoge_alias { shift->hoge(@_) }
これでもいいんですが、hogeメソッドでcaller関数なんかを使って何かしら処理している場合に問題になる可能性があるので、gotoとか使ってみる。
sub hoge_alias { goto &hoge }
だけど、型グロブ期な僕は下記のようにするのが好きです。
*hoge_alias = \&hoge;
ただし、use warningsとかしてると「Name "main::hoge_alias" used only once: possible typo(一回しか使って無いやんけ!)」という警告が出るので、
sub hoge_alias; *hoge_alias = \&hoge;
とか
{ no warnings; *hoge_alias = \&hoge; }
みたいにしとけばいいのかな。
あと、問題点としてはgoto使うにしても型グロブ使うにしてもClass::C3とかでhogeメソッド内でnext::methodを使ってる場合は
hoge_aliasメソッドではなくhogeメソッドに行ってしまうところかな。
package Hoge; use strict; sub hoge_alias { print "Hoge::hoge_alias\n" } sub hoge { print "Hoge::hoge\n" } package Muge; use strict; use base qw/Hoge/; use Class::C3; sub hoge { my $self = shift; $self->next::method; } sub hoge_alias; *hoge_alias = \&hoge; Muge->hoge_alias; # Hoge::hoge と表示される
これはどうしようも無いのかな。
Class::C3を使ってるようなメソッドのエイリアスを作ることはコピペ以外に原理的には不可能?
一応文字列で保持しておいてevalするってやり方もあるけど
for my $subname (qw/hoge hoge_alias/){ eval sprintf q{ sub %s { my $self = shift; $self->next::method; } },$subname; }
何か美しくないしね。
というかあれだな。そもそもClass::C3使ってるようなメソッドのエイリアスメソッドなんか作ろうってのがおかしいんだよ。
というわけで基本エイリアスメソッド生成には型グロブ。コレで決定。