package Class::Rebirth; ## Brings a deserialized class back to life
$Class::Rebirth::VERSION = '1.000';
use strict;
use Carp;
use vars qw(@ISA @EXPORT %EXPORT_TAGS $VERSION);
use Exporter;
use List::MoreUtils qw(uniq);
@ISA = qw(Exporter);
%EXPORT_TAGS = ( all => [qw(
rebirth
)] );
Exporter::export_ok_tags('all');
# When a class is deserialized from saved dump it still holds the information,
# but the methods are not accessable anymore.
#
# So far a run with eval would do the rebirth, but that does only work if
# needed classes are required/ used. Here the Class::Rebirth also cares about requiring
# the needed classes nested in the potential object.
#
# A death class I call zombie (has nothing todo with processes), as they look like
# normal classes but have no living methods.
#
#
#
# SYNOPSIS
# ========
#
# use Class::Rebirth 'rebirth';
# my $object = rebirth( $zombie );
#
#
# or
#
# use Class::Rebirth;
# my $object = Class::Rebirth::rebirth( $zombie );
#
#
# It is also able to use a data dump instead of an object.
#
# my $object = Class::Rebirth::rebirth( $dump );
#
#
#
# AUTHOR
# ======
# Andreas Hernitscheck ahernit(AT)cpan.org
# @brief Takes a death object and and creates a living object of it.
# Such a zombie class looks like a normal class when you dump it.
# But it is not alive, means methods won't work. An Effect which
# happens by deserializing classes from a store (dumped data).
sub rebirth { # $object ($zombie)
my $zombie = shift or croak "requires zombie";
my $obj;
# if zombie is dump string, build an object first
if ($zombie =~ /^\$/){
$zombie = _createObjectByDump( $zombie );
}
my @pkgs = _getUsedPackagesOfObject($zombie);
foreach my $p (@pkgs){ print $p;
eval("require $p;");
if ($@){die $@};
}
## rerun an eval to realy bring it back to life
my $target;
my $ser = Data::Dumper->Dump([$zombie],['$target']);
eval $ser;
if ($@){die $@};
return $zombie;
}
# Can use a data dump'ed string which
# starts with a variable assignment like $VAR1=
# @return object
sub _createObjectByDump{
my $dump = shift;
my $target;
# relace var with own var
$dump =~ s/^(\$[a-z0-9]+)/\$target/i;
eval $dump;
if ($@){die $@};
return $target;
}
# Does a deep search in object for
# used package names.
# @return list of packages
sub _getUsedPackagesOfObject{
my $obj = shift;
my @list;
if (Scalar::Util::blessed $obj){
push @list, ref($obj);
}
foreach my $k (keys %$obj){
my $value = $obj->{$k};
print ref $obj->{$k}."< \n";
# walk down any hash to find more blessed objects
if (ref $obj->{$k} eq 'HASH'){
my @sublist = _getUsedPackagesOfObject( $value );
push @list, @sublist;
}
# is blessed object
if (Scalar::Util::blessed $value){
push @list, ref($obj);
my @sublist = _getUsedPackagesOfObject( $value );
push @list, @sublist;
}
}
# make unique strings
@list = uniq @list;
return @list;
}
1;
#################### pod generated by Pod::Autopod - keep this line to make pod updates possible ####################
=head1 NAME
Class/Rebirth.pm - Class/Rebirth.pm
=head1 SYNOPSIS
use Class::Rebirth 'rebirth';
my $object = rebirth( $zombie );
or
use Class::Rebirth;
my $object = Class::Rebirth::rebirth( $zombie );
It is also able to use a data dump instead of an object.
my $object = Class::Rebirth::rebirth( $dump );
=head1 DESCRIPTION
When a class is deserialized from saved dump it still holds the information,
but the methods are not accessable anymore.
So far a run with eval would do the rebirth, but that does only work if
needed classes are required/ used. Here the Class::Rebirth also cares about requiring
the needed classes nested in the potential object.
A death class I call zombie (has nothing todo with processes), as they look like
normal classes but have no living methods.
=head1 REQUIRES
L<Class::Rebirth>
L<Class::Rebirth>
L<List::MoreUtils>
L<Data::Dumper>
L<Exporter>
L<Scalar::Util>
L<Carp>
=head1 METHODS
=head2 rebirth
my $object = rebirth($zombie);
Takes a death object and and creates a living object of it.
Such a zombie class looks like a normal class when you dump it.
But it is not alive, means methods won't work. An Effect which
happens by deserializing classes from a store (dumped data).
=head1 AUTHOR
Andreas Hernitscheck ahernit(AT)cpan.org
=cut