in reply to limiting the scope of bless
That can be done easily with an object that takes charge of the reblessing and which reverts what it did at destruction time. Your illustration code would look like:
The output should be:package boo; sub to_s { "a boo" }; package bar; sub to_s { "a bar" }; package main; sub doit { my $boo = shift; my $reblesser = Reblesser->new; $reblesser->rebless($boo, "bar"); print "within: ", $boo->to_s, "\n"; # "a bar" # here the scope of the reblesser ends and so the reblessing it did } my $obj = bless {}, 'boo'; print "before: ", $obj->to_s, "\n"; # "a boo" doit($obj); print "after: ", $obj->to_s, "\n"; # "a boo" again
This way you just have to be sure that the scope in which you want to limit the reblessing is the same as the scope of the reblesser object. A trivial implementation of such reblesser would be:$ perl reblesser.pl before: a boo [DEBUG] reblessing boo=HASH(0x102efcf8) to bar within: a bar [DEBUG] reverting blessing on bar=HASH(0x102efcf8): back to boo after: a boo
package Reblesser; use strict; use warnings; use base qw(Class::Accessor); __PACKAGE__->mk_accessors(qw(reblessed)); use Scalar::Util qw(blessed); # reblessed holds pairs [ (object => original_package) ] sub new { my $self = shift; return $self->SUPER::new({ reblessed => [] }); } sub rebless { my $self = shift; my $obj = shift; my $package = shift; die "not blessed" unless blessed $obj; push @{$self->reblessed}, [ $obj, blessed $obj ]; warn "[DEBUG] reblessing $obj to $package\n"; return bless $obj, $package } sub DESTROY { my $self = shift; for (@{$self->reblessed}) { my ($obj, $pkg) = @$_; warn "[DEBUG] reverting blessing on $obj: back to $pkg\n"; bless $obj, $pkg; } }
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: limiting the scope of bless
by jaa (Friar) on Apr 25, 2007 at 11:10 UTC | |
by bunnyman (Hermit) on Apr 25, 2007 at 13:53 UTC | |
Re^2: limiting the scope of bless
by aufflick (Deacon) on Apr 27, 2007 at 00:39 UTC |
In Section
Seekers of Perl Wisdom