in reply to Re: Storable with hash of hashes (reference problem?)
in thread Storable with hash of hashes (reference problem?)

I got a little confused about that, because in the section of the perlreftut that discuss the "Arrow Rule" it says the arrow isn't necessary between two subscripts. I guess that means it's required in this case? If $reports{$year} and $reports->{$year} are different variables, and $reports->{$year} is a hash reference, then what is $reports{$year}?

In any event, I've added use strict; and your printit sub, and now the "new data" is identical to the "old data". Here's the code:

#!/usr/bin/perl use Storable qw(lock_nstore lock_retrieve); use strict; my $reports; my %reports; my $label; # load the file if (-e "reporting.storable") { $reports = lock_retrieve("reporting.storable") || die "Couldn't lock_retrieve reporting.storable: $!\n"; } $label = 'old data'; printit(); # generate some random data for (0 .. 10) { my @myyears = (2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 201 +0, 2011); my $fiscal_year = $myyears[int(rand 9)]; my @myquarters = ('Q1', 'Q2', 'Q3', 'Q4'); my $qua = $myquarters[int(rand 3)]; my @myfiles = ('foo.txt', 'bar.dat', 'bap.zip', 'baz.tgz', 'zif.do +c', 'blu.shn', 'sng.mp3', 'zap.pif', 'fiz.pdf', 'shz.nit'); my $filen = $myfiles[int(rand 9)]; my @mytitles = ('fooey', 'dooey', 'looey', 'zooey', 'gooey', 'hooe +y', 'tooey', 'pooey', 'rooey', 'blooey'); my $title = $mytitles[int(rand 9)]; my @mydescriptions = ('desc1', 'desc2', 'desc3', 'desc4', 'desc5', + 'desc6', 'desc7', 'desc8', 'desc9', 'desc10'); my $description = $mydescriptions[int(rand 9)]; # update the data $reports{$fiscal_year}{$qua}{$filen}->{title} = "$title"; $reports{$fiscal_year}{$qua}{$filen}->{description} = "$descriptio +n"; } $label = 'new data'; printit(); # save the file $reports = \%reports ; lock_nstore ($reports, "reporting.storable") || die "Couldn't lock_nstore reporting.storable: $!\n"; sub printit { my $year; my $quarter; my $file; # print the hash print "\n======== BEGIN $label =========\n"; foreach my $year ( sort keys %{$reports} ) { print "$year: \n"; foreach my $quarter(sort keys %{$reports->{$year}}){ print " $quarter: \n"; foreach my $file (sort keys %{$reports->{$year}{$quarter} +} ) { print " Filename: $file\n"; print " Title: $reports->{$year}{$quarter}{$f +ile}{title}\n"; print " Description: $reports->{$year}{$quarter}{$f +ile}{description}\n\n"; } } } print "\n======== END $label =========\n"; }

Still stumped! I'm going to write another version using Data::Dumper just for fun, unless anyone sees any caveats with that approach for this data structure, but I'd also really like to know how to do this with Storable.

Thanks for your help!

Replies are listed 'Best First'.
Re: Re: Re: Storable with hash of hashes (reference problem?)
by Roger (Parson) on Oct 09, 2003 at 02:14 UTC
    Your problem is almost fixed, except that you called the second printit() before you assigned $reports to the new hash table. So your second printit() is still printing the old hash table.

    Change your code to:
    # save the file $reports = \%reports ; printit();
    And you will print your second hash table correctly.

    If $reports{$year} and $reports->{$year} are different variables, and $reports->{$year} is a hash reference, then what is $reports{$year}?

    This is because $reports is a reference that points to the %reports hash table. The %reports hash table gets created after your first printit(). In your original code, in your first printit(), you tried to refer to the loaded $reports to get your year values, and then refer to undefined %reports with $reports{$year}, which has not yet been initialized. Because you haven't used strict at the beginning of your code, Perl happily created the undefined variable for you.

    Cheers. Roger.
Re: Re: Re: Storable with hash of hashes (reference problem?)
by ChrisR (Hermit) on Oct 09, 2003 at 02:02 UTC
    The only caveat I can think of with Data::Dumper is that the data is evaled. That could cause execution of evil code. However, since you are creating this data yourself, the decision to trust the data or not may require a little investigation into the general security of your box.

    I am trying to figure out Storable as a result of your post. So far I have found that it appears to be much faster at storing arrays than Data::Dumper. When storing a hash, the both seem to be about the same speed. What I don't like aoubt it is Storable returns a reference to a hash or array instead of the actual data.

    Oh yeah, there was a question:
    If $reports{$year} and $reports->{$year} are different variables, and $reports->{$year} is a hash reference, then what is $reports{$year}?
    From what little I know about it, a reference is just a scalar that points a different location. Kind of like pointers in C. $reports{year} (in relation to your original example) would be the data you created at the beggining of your script and $reports->{year} would be a reference (pointer) to the data that you read using Storable. They are two entirely different chunks of data and one can be changed without affecting the other.
      $reports{$year} is %reports. $reports->{year} is dereferencing a hash ref contained in a scalar. The arrow is not needed for things like $array[1][2] where $array[1] is actually an array ref.