Perl: オブジェクトのunbless
perlのblessはオブジェクトにクラス名をマッピングする命令です。
my $a = bless {}, "AA::BB::CC"; print ref($a), "\n";
を実行すると、AA::BB::CCが表示されます。
ほかの名前でblessし直すとその名前で古い対応関係が上書きされます。ではその対応関係を解除するにはどうすればよいのでしょう。bless $a, "HASH"などとすれば、ref関数の結果はblessする前と同じになりますが、依然としてblessされたままです。たとえば、Scalar::Utilのblessed命令を実行すると、blessされたままであることがわかります。
blessの解除を行うために、Data::Structure::Utilパッケージのunblessという命令が使えます。
use Scalar::Util qw(blessed); use Data::Structure::Util qw(unbless); my $a = bless {}, "TEST"; unbless($a); print "Hello\n" if blessed($a);
これを実行しても、Helloは表示されません。同じ用途で、Acme::Damnのdamnも使えます。
use Scalar::Util qw(blessed); use Acme::Damn qw(damn); my $b = bless {}, "TEST"; damn($b); print "Hello\n" if blessed($b);
これも、同じ結果になります。どちらも、ソースを見てみるとperlだけではこれは記述できなくて、xsのなかで、
SvOBJECT_off(sv);
を実行しています。blessされたオブジェクトであることを表しているフラグを0にしているわけです。一旦blessしたオブジェクトに対して、そのblessを解除するのって、実はそんなに簡単なことではないんですね。