in reply to Re-blessing || Re-constructing objects
Reblessing is one approach for doing foreign inheritance in inside-out objects without using a facade. For example, what if you want to keep additional state with a filehandle object? The following code is adapted from File::Marker:
package File::With::State; use strict; use warnings; use Scalar::Util qw( refaddr ); use base 'IO::File'; my %stash; # hold inside-out state sub new { my $class = shift; # create the object and rebless my $self = IO::File->new(); bless $self, $class; # initialize the object $stash{ refaddr $self } = {}; $self->open( @_ ) if @_; return $self; } sub stash { my ($self, $key, $value) = @_; return unless $key; $stash{ refaddr $self }{ $key } = $value if $value; return $stash{ refaddr $self }{ $key }; } # Note: this simple example is not thread-safe and also # needs a destructor to avoid leaking memory
The advantage of this over the facade pattern is that you can use the object directly wherever you would use a filehandle.
my $fh = File::With::State->new( 'some_file' ); my @lines = <$fh>; $fh->stash( line_count => scalar @lines );
I think this use of reblessing is "safe" because it reblesses into a subclass, which means that all the methods of the original class are available (although they could be overridden as usual with subclassing). No functionality is lost through the reblessing.
-xdg
Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.
|
|---|