http://www.perlmonks.org?node_id=433705


in reply to Re^2: In need of a Dumper that has no pretentions to being anything else.
in thread In need of a Dumper that has no pretentions to being anything else.

Note that DD only gets it right with print Dumper([\%s, $s]) but not with print Dumper([$s, \%s])

For that you need a better dumper. I wonder if its arguable that the tracking you are talking about disabling is actually not required for Purity=0 dumps.

---
demerphq

Replies are listed 'Best First'.
Re^4: In need of a Dumper that has no pretentions to being anything else.
by fergal (Chaplain) on Feb 23, 2005 at 19:34 UTC
    Depends on what you mean by "right". I get
    $VAR1 = [ \1, { 'key' => ${$VAR1->[0]} } ];
    which can't be evaluated correctly by Perl's eval but it does contain all the necessary information. A human can see what's going on and it's probably possible to write something that would reconstruct the correct sturucture but it would involve some sort of constraint solver.

    Purity just controls whether it should be compatible with eval(). Even with Purity=0, this information should be preserved otherwise certain structures would have identical output even though they're not identical.

    Deepcopy controls whether we care about cross references so it definitely should be dropped when you have Deepcopy=1.

      Depends on what you mean by "right".

      Something that is reasonably close to valid perl that will recreate the original data. In this case the code is just plain wrong, with or without Purity mode.

      this information should be preserved otherwise certain structures would have identical output even though they're not identical.

      You mean like Data::Dumper does below? (And Data::Dump::Streamer does not?)

      probably possible to write something that would reconstruct the correct sturucture but it would involve some sort of constraint solver

      See Data::Dump::Streamer for a dumper that handles these things properly. DD does a single pass over its dataset, and a depth first one at that, this almost guarantees that it will get things like this wrong. These are very old bugs, first raised by merlyn years ago (see a bug report that involves the dog pound) that still havent been fixed, and frankly probably will never be fixed.

      ---
      demerphq

        I don't get it. When Purity=0 DD, doesn't claim to reevaluate correctly and it's frequently more readable. When Purity=1, it seems to work perfectly for me.

        Here's something that takes your examples above, DDDumps them with Purity=1 and reevals the string and then shows the Streamer version of the original and of the evaled.

        use Data::Dumper; use Data::Dump::Streamer; $Data::Dumper::Purity=1; my ($x,$y); $x=\$y; $y=\$x; test([$x, $y]); my $ary=[]; $ary->[0]=\$ary->[1]; $ary->[1]=\$ary->[0]; test($ary); sub test { my $VAR1; my $s = shift; my $d = Dumper($s); my $s2 = eval "$d;\$VAR1"; die $@ if $@; print "original---------------\n"; print Dump($s); print "DDed---------------\n"; print Dump($s2); print "\n" } __END__ original--------------- $ARRAY1 = [ \do { my $v = 'V: $ARRAY1->[1]' }, \do { my $v = 'V: $ARRAY1->[0]' } ]; ${$ARRAY1->[0]} = $ARRAY1->[1]; ${$ARRAY1->[1]} = $ARRAY1->[0]; DDed--------------- $ARRAY1 = [ \do { my $v = 'V: $ARRAY1->[1]' }, \do { my $v = 'V: $ARRAY1->[0]' } ]; ${$ARRAY1->[0]} = $ARRAY1->[1]; ${$ARRAY1->[1]} = $ARRAY1->[0]; original--------------- $ARRAY1 = [ 'R: $ARRAY1->[1]', 'R: $ARRAY1->[0]' ]; $ARRAY1->[0] = \$ARRAY1->[1]; $ARRAY1->[1] = \$ARRAY1->[0]; DDed--------------- $ARRAY1 = [ \do { my $v = 'V: $ARRAY1->[1]' }, \do { my $v = 'V: $ARRAY1->[0]' } ]; ${$ARRAY1->[0]} = $ARRAY1->[1]; ${$ARRAY1->[1]} = $ARRAY1->[0];

        The first one comes out identical. The second one is not textually identical but if ${$x} = $y means the same thing as $x = \$y then I can't see what DD did wrong. Do they mean the same thing?