わかっててわざとやるんだったらいいんですけど、そうじゃないなら定石通りに書くべきだと思います。
5 sub new { 6 my $c = shift; 7 bless $c; 8 } 33 my $human = Human::new({'name' => 'ビンゴ', 34 'age' => 1, 35 'bag' => {} 36 });
この書き方の問題点は二つあります。まず、コンストラクタを Human::new のように静的呼び出ししていること。もう一つが、blessを1引数で使っていることです。
確かにblessは1引数で使っても、デフォルトとして定義された時点でのパッケージへリファレンスを紐づけてくれます。ってことは、わざわざクラス名が渡るように書かない方が、冗長じゃなくていいじゃん? と思われるかもしれないですが、それはちょっと早計です。
なぜなら、この書き方では継承ができないからです。継承しようと頑張って以下のコードを書いてみても、うまく行きません。
package Hero; use base qw/Human/; *new = \&Human::new; sub get_old { warn "The hero doesn't get older."; } package main; my $human = Hero::new( ... 略 ...);
まず、newを静的呼び出ししているために、せっかくHumanクラスを継承してもHeroからHumanのnewが探索されません。そのため、Humanクラスでもnew関数を用意する(*new = の部分)必要があります。
そして、blessに第二引数を渡していないため、Hero::new からは Hero ではなく Humanに紐づいたオブジェクトが返ってきます。そのため、オーバーライドした get_old が呼ばれません。
以下がきちんと継承できる書き方となります。
package Human; sub new { my $class = shift; my ($ref_param) = @_; bless $ref_param, $class; } ... 色々略 ... package Hero; use base qw/Human/; sub get_old { warn "The hero doesn't get older.\n"; } package main; my $human = Hero->new({ .. 略 .. }); ... 色々略 ...
こう書くことで、サブクラス名 'Hero' が Human::new まで渡って行き、 Human::new 内でうまく 'Hero' に bless されるようになります。
なお、perlmodlib的には、newは以下のように書くべきとなってます。*1。
Use the two argument form of bless to bless into the class name given as the first parameter of the constructor, e.g.,:
(.. 中略 ..)
sub new { my $self = shift; my $class = ref($self) || $self; return bless {}, $class; }
*1:ただしperl - 万能なnewの書き方にもある通りPBP的にはこのコードはNG。