##結論
blessは、オブジェクトを返すんじゃなくて、
受け取ったリファレンス自体をオブジェクト化して返す
→blessは破壊的メソッド。
これを知らないと、以下の罠にはまります。
##追記(2013/11/19)
package Class1;
sub new{
my ($class, %args ) = @_;
bless +{
hoge => 'initial value',
%args,
}, $class;
}
Class1->new( hoge => 1)
cpanを見ると、上記のように書くのが一般的なようです。
そもそも参照で渡すな、って話でした。
##例
package Class1;
sub new{
my ($class, $args ) = @_;
bless $args, $class;
}
package Class2;
sub new{
my ($class, $args ) = @_;
bless $args, $class;
}
と適当なクラスを定義します。
my $args = {hoge => 'hoge'};
my $obj1 = Class1->new($args);
my $obj2 = Class2->new($args);
print ref $args; # => Class2
print ref $obj1; # => Class2
$obj1がClass2なんだぜこれ…
$argsもちゃっかりオブジェクトになってるし…
対策
$obj1をきちんとClass1にするためには、
以下のうちどれかをすればいいです。
- 無名ハッシュで渡す
- そのままblessせずに、無名ハッシュをblessする
-
bless Clone::clone($args), $class
とする
なお、unblessも破壊的です。