Why Dumper output is not evaluated correcty?

Viewed 61

I try to eval output of Dumper for pretty simple hashref, where two keys have same value (ref to another hash):

#!/usr/bin/env perl

use strict; use warnings;
use Data::Dumper;

my $foo = { data => 1 };
my $boo = {
  x => $foo,
  y => $foo,
};

my $VAR1;
my $bar = eval( Dumper( $boo ) );

print Dumper( $boo );
print Dumper( $bar ); 

I expect the $boo and $bar to have same structure, but eval seems not solve inner-ref $VAR1->{'x'} correctly, I hoped last 2 lines to print same string:

$VAR1 = {
          'x' => {
                   'data' => 1
                 },
          'y' => $VAR1->{'x'}
        };

But second has x or y undefined (depending which was referenced in literal form):

$VAR1 = {
          'x' => {
                   'data' => 1
                 },
          'y' => undef
        };

I tried simple usage part on doc, and it gave fine results with much more complex structure (no strict, yet), but I can' accomplish it with my data with 2 references to same hash.

What am I missing here?

1 Answers

To correctly capture references inside a structure, you need to set the Purity flag (see the Data::Dumper documentation for details).

$Data::Dumper::Purity = 1;

It's not enough, though, as Dumper($boo) will now return

$VAR1 = {
          'y' => {
                   'data' => 1
                 },
          'x' => {}
        };
$VAR1->{'x'} = $VAR1->{'y'};

So, you can't just eval this string, you also need to return $VAR1 from it.

To prevent the purity flag interfering with other parts of the code, you can set it locally:

#!/usr/bin/perl
use strict;
use warnings;

use Data::Dumper;

my $foo = { data => 1 };
my $boo = {
    x => $foo,
    y => $foo,
};

my $VAR1;
my $bar = do {
    local $Data::Dumper::Purity = 1;
    eval Dumper( $boo );
    $VAR1
};

print Dumper( $boo );
print Dumper( $bar );
Related