Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a hash of hashes that I want stored in a file. I don't want to "hand parse" it and I don't like the look of MLDBM. I thought I'd use Data::Dumper since

"The return value can be evaled to get back an identical copy of the original reference structure.

But I cannot figure out how this is done.
#!/usr/bin/perl -w use strict; use Data::Dumper; my @ray=qw(bob me other); my %hash; foreach (@ray) {my %tmp=("one", "$_+1", "two", "$_+2", "three", "$_+3" +); %{$hash{$_}}=%tmp} my $ref=\%hash; my $r2=Dumper($ref); print $r2; $Data::Dumper::Purity=1; #?????????eval??
The goal would be to turn $r2 back into a hash of hashes.

Replies are listed 'Best First'.
Re: use of eval and Data::Dumper
by lamp (Chaplain) on Sep 27, 2008 at 16:42 UTC
    You can use YAML as an alternative to Data::Dumper for storing and retrieving HoH.
    #!/usr/bin/perl -w use strict; use YAML qw( DumpFile LoadFile ); my @ray=qw(bob me other); my %hash; foreach (@ray) {my %tmp=("one", "$_+1", "two", "$_+2", "three", "$_+3" +); %{$hash{$_}}=%tmp}; my $file_to_store = 'dump.txt'; DumpFile( $file_to_store , \%hash ); my $loaddata = LoadFile($file_to_store);
Re: use of eval and Data::Dumper
by broomduster (Priest) on Sep 27, 2008 at 15:32 UTC
    As an alternative to eval'ing your stored HoH, have a look at Storable (part of the Perl distribution).
      Thanks broomduster, Storable might be better.

      But I did find the solution:
      #!/usr/bin/perl -w use strict; use Data::Dumper; my @ray=qw(bob me other); my %hash; foreach (@ray) { %{$hash{$_}}=("one", "$_+1", "two", "$_+2", "three", "$_+3") } my $ref=\%hash; $Data::Dumper::Terse=1; # remove "$VAR" in output my $r2=Dumper($ref); my $answer = eval $r2; print Dumper($answer);
        No, you want Purity=1, and Terse=1 is a step away from what you want. Better:
        #!/usr/bin/perl -w use strict; use Data::Dumper; my $dump; { # Writer # ----- my $hash = {}; my @ray=qw(bob me other); foreach (@ray) { %{$hash->{$_}} = ( one => $_+1, two => $_+2, three => $_+3, ); } print(Dumper($hash)); $dump = Data::Dumper->new([ $hash ], [qw( $hash )]) ->Purity(1) ->Dump(); } { # Reader # ------ my $hash; eval "$dump; 1" or die $@; print(Dumper($hash)); }
Re: use of eval and Data::Dumper
by moritz (Cardinal) on Sep 27, 2008 at 16:44 UTC
    You can turn $r2 back into a data structure like this:
    my $data = eval "no strict; $r2";

    The no strict is needed because the output from Data::Dumper has new variables without declaring them. Instead you could also tweak Data::Dumper's option prior to dumping.

      (Update: D'oh, I missed that "Terse" had already been mentioned above.)

      To the OP, not moritz: I don't recommend Data::Dumper. YAML or Storable (or even JSON if it fits with what you're doing; JSON::XS is--last I checked--the fastest serializer in Perldom) are preferable. I'm just adding that you can get Data::Dumper to emit raw data (no variable at all so you can skip the no strict) this way-

      use Data::Dumper; $Data::Dumper::Terse = 1; # No VARs. $Data::Dumper::Indent = 1; # Less indenting. my %what = ( foo => [ 1 .. 3 ], wacka => 1 ); print Dumper \%what; __END__ { 'wacka' => 1, 'foo' => [ 1, 2, 3 ] }
Re: use of eval and Data::Dumper
by repellent (Priest) on Sep 27, 2008 at 18:37 UTC
Re: use of eval and Data::Dumper
by planetscape (Chancellor) on Sep 28, 2008 at 11:11 UTC