My apologies for the abbreviated explaination, I was more asking about procedure than code, but since
there is interest ;)
The culprit is here:
@@ -395,10 +395,7 @@
if ($realpack) { # we have a
blessed ref
$out .= ', \'' . $realpack .
'\'' . ' )';
- my $toaster = $s->{toaster};
- if (UNIVERSAL::can($val,
$toaster)){
- $out .= '->' .
$s->{toaster} . '()' if $s->{toaster} ne '';
- }
+ $out .= '->' . $s->{toaster}
. '()' if $s->{toaster} ne '';
$s->{apad} = $blesspad;
}
$s->{level}--;
Without the patch, if I set up an
instance of Data::Dumper as such:
my $dumper = new
Data::Dumper(undef,'thaw')->
Freezer('DUMPER_freeze')->Toaster('DUMPER_thaw');
and one or more of the serialized objects is frozen like such:
my $freeze=$dumper->Values($ref_to_some_object)->Dump;
All serialized output will be of the form:
bless(DATA, CLASS)->(DUMPER_thaw);
so when I attempt to reconstitute it (thaw it):
my $thaw; # 'thaw' is the handle that I
told DD to use
eval $freeze # sets thaw
DD calls the DUMPER_thaw method on the
object, whether it had it or not. If it has it, fine, use it.
Otherwise, DD should use its default thawing capabilities.
Currenlty it will die with:
WARNING(Freezer method call failed):
Can't locate object method "DUMPER_freeze" via package
"TestAutoDBOutside_1" at
/tools/lib/perl5/5.8.4/i686-linux-thread-multi/Data/Dumper.pm line
158.
...
Attempt to free temp codematurely: SV
0x83ee194 at
/tools/lib/perl5/5.8.4/i686-linux-thread-multi/Data/Dumper.pm line
501.
Scalars leaked: 1
which all look like warnings, but the
object never gets thawed.
Here is the test wich I included with
the patch that explains things more thoroughly (it should only pass
after DD is patched):
package DD_test;
use lib qw(../blib/lib ../blib/arch);
use Data::Dumper;
use Test::More qw/no_plan/;
$Data::Dumper::Useperl = 1;
my $DUMPER=new
Data::Dumper([undef],['thaw'])->Purity(1)->Indent(1)->Freezer('DUMPER_
+freeze')->Toaster('DUMPER_thaw');
my $f = new freezable;
my $t = new unthawable;
$f->{_OTHER} = new unthawable;
$t->{_OTHER} = new freezable;
my ($thaw);
print "-" x 100, "\n";
print "Freezable\n";
print "-" x 100, "\n";
my $th = $DUMPER->Values([$f])->Dump;
#print Dumper $th;
eval $th; #sets $thaw
#print Dumper $thaw;
isa_ok($thaw,'freezable');
is($thaw->oid, 1);
isnt($thaw->can('DUMPER_thaw'),undef);
is($thaw->{_OTHER}->oid, 3);
is($thaw->{_OTHER}->can('DUMPER_thaw'),undef);
undef $thaw;
print "-" x 100, "\n";
print "Unfreezable\n";
print "-" x 100, "\n";
my $th2 = $DUMPER->Values([$t])->Dump;
#sets $thaw
#print Dumper $th2;
eval $th2; #sets $thaw
#print Dumper $thaw;
is($thaw->oid, 3);
is($thaw->can('DUMPER_thaw'),undef);
is($thaw->{_OTHER}->oid, 1);
isnt($thaw->{_OTHER}->can('DUMPER_thaw'),undef);
## freezable package
package freezable;
sub new {
my($self)=@_;
return bless {}, $self;
}
sub oid {
return 1;
}
sub DUMPER_freeze {
my($self)=@_;
print ">>>
DUMPER_freeze ",$self->oid,"\n";
$self->{_OID} = $self->oid;
$self->{_CLASS} = ref $self;
return $self;
}
sub DUMPER_thaw {
my($self)=@_;
print "<<< DUMPER_thaw
", $self->oid, "\n";
return $self;
}
sub oid2object {
shift @_ unless ref($_[0])=~/DBI::/;
%__PACKAGE__::OID_2_OBJECT=shift @_
if @_;
return \%$__PACKAGE__::OID_2_OBJECT;
}
## unthawable package (no DUMPER_freeze, DUMPER_thaw method)
package unthawable;
sub new {
my($self)=@_;
return bless
{_OID=>$self->oid,_CLASS=>$self}, $self;
}
sub oid {
return 3;
}
|