in reply to Push corrupting data

zengargoyle nailed your problem down, but I played around a bit to reproduce your problem and have some extra information that might interest you. Specifically, the reason you get lots of references to $output->[1] in your last dump is that Data::Dumper does not do deepcopies by default: if it encounters array elements that point to the same thing, it prints a self-reference (hence $output->[1]). You can control this behaviour with $Data::Dumper::Deepcopy. E.g.
use strict; use Data::Dumper; my $hashref= { 'one' => 'two' }; my $aryref=[ $hashref ]; push @$aryref, $hashref; push @$aryref, $hashref; print "Without Deepcopy: ".Dumper($aryref); $Data::Dumper::Deepcopy=1; print "With Deepcopy: ".Dumper($aryref); print "Without Data::Dumper:\n"; print join("\n", @$aryref); __END__ Without Deepcopy: $VAR1 = [ { 'one' => 'two' }, $VAR1->[0], $VAR1->[0] ]; With Deepcopy: $VAR1 = [ { 'one' => 'two' }, { 'one' => 'two' }, { 'one' => 'two' } ]; Without Data::Dumper: HASH(0x8111a94) HASH(0x8111a94) HASH(0x8111a94)
So, the weird stuff you saw was actually a Data::Dumper artifact. There are actually three identical references in the array, but Data::Dumper only derefs one by default.

Anyway, we now return you to the scheduled programme.

CU
Robartes-

Replies are listed 'Best First'.
Re: Re: Push corrupting data
by demerphq (Chancellor) on Mar 13, 2003 at 12:52 UTC

    You can control this behaviour with $Data::Dumper::Deepcopy. E.g

    Actually $Data::Dumper::Deepcopy is probably not the best way to understand whats going on here. $Data::Dumper::Deepcopy makes a copy of items that are referenced multiple times (but are not cyclic). So that means that the output is not the same as the input. Whereas in "normal" mode Dumper uses a shorthand that is easy to read (ie its clear whats going on to a reasonable well versed perl programmer) but is not necessarily actually valid perl. A better approach is to use $Data::Dumper::Purity so that when the output is less clear to read, but much more accurate. An example (but using the OO form and not the global var form of controlling the behaviour)

    #!perl -lw use strict; use Data::Dumper; my $hash={"A".."F"}; my $array=[$hash,'foo',$hash]; print $_ for "Normal:", Data::Dumper->new([$array],[qw(array)])->Dump(), "Deepcopy:", Data::Dumper->new([$array],[qw(array)])->Deepcopy(1)->Dum +p(), "Purity:", Data::Dumper->new([$array],[qw(array)])->Purity(1)->Dump( +), "Terse:", Data::Dumper->new([$array],[qw(array)])->Indent(1)->Terse +(1)->Dump();

    outputs

    And the only one that is both valid (ie it compiles) and correct (ie it outputs exactly the same thing as its input) is the one labeled "Purity".

    Deepcopy is useful if for some reason you _don't_ want anythiong referenced more than once (if possible). Note that these settings combine, so to apply Deepcopy to for a cyclic and multiply referenced data structure like the following you would need Purity _and_ Deepcopy.

    #!perl -lw use strict; use Data::Dumper; my $hash ={'A'..'F'}; my $array=[]; @$array=($hash,'foo',$hash,[$hash,'bar',$hash,$array]); print $_ for "Normal:", Data::Dumper->new([$array],[qw(array)])->Dump(), "Deepcopy:", Data::Dumper->new([$array],[qw(array)])->Deepcopy(1)->Dum +p(), "Purity:", Data::Dumper->new([$array],[qw(array)])->Purity(1)->Dump( +), "PureDeep:", Data::Dumper->new([$array],[qw(array)])->Deepcopy(1)->Pur +ity(1)->Dump();

    outputs

    The moral of the story is that if accuracy and validness is required then Purity() is required. See Data::Dumper for more details.


    ---
    demerphq