Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Re: limiting the scope of bless

by ferreira (Chaplain)
on Apr 25, 2007 at 10:58 UTC ( #611964=note: print w/replies, xml ) Need Help??

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:

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
The output should be:
$ perl 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
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:
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
    Most excellent! Doh - I never thought of using scope on a separate object and invoking the $priest->DESTROY to unbless!

    Just to confirm - Is DESTROY actually and reliably called when leaving scope, rather than later in a garbage sweep? Wouldn't want the blessing to be too sticky!



      Yes, perl does not have a background thread for its garbage collector.
Re^2: limiting the scope of bless
by aufflick (Deacon) on Apr 27, 2007 at 00:39 UTC

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://611964]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2023-01-28 07:39 GMT
Find Nodes?
    Voting Booth?

    No recent polls found