Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

References and state-saving

by Guildenstern (Deacon)
on Jan 13, 2001 at 01:20 UTC ( #51477=perlquestion: print w/replies, xml ) Need Help??
Guildenstern has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing a script that occasioanlly needs to save its state, make a guess and see if that guess leads to a logical end result. If the guess is bad, we need to backtrack and restore state. The main information is stored in a hash whose values are AoAs. e.g.:
$hash{$a}->[$b]->[$c] = $d;

When I need to save state, I do something like this:
sub save_state { my %save_hash = %main_hash; my @save_info; push(@save_info,\%save_hash); push(@save_info,\$aVar); # etc. for all vars to save push(@save_stack,\@save_info); }

That part works fine. The problems show up when I try to restore from the stack. It seems that any values I change in %main_hash are now in the %save_hash! Am I right to assume that this is somehow related to the fact that the values of the hash are array refs? Should I explicitly copy all of the info in the hash out before I save it?

Negaterd character class uber alles!

Replies are listed 'Best First'.
Re: References and state-saving
by Fastolfe (Vicar) on Jan 13, 2001 at 01:21 UTC
    You can use something like 'dclone' in Storable to achieve the "deep copy" you're looking for. Yes, since the values in one structure reference the same values in the other, they'll both change the same thing when modifications are made. You may have some luck trying to localize your changes to a specific function.
Re: References and state-saving
by c-era (Curate) on Jan 13, 2001 at 02:12 UTC
    The reason %save_hash changes is because you are copy a referance to an array. If you print out $hash{$a} you will see it contains a referance to an array, and that is what you are putting into $save_hash{$a}. You need to work your way down to copying the values, one way to do this is below:
    sub save_state { my %save_hash; # foreach is your friend foreach $key (keys (%main_hash)){ foreach $num1 (0..$#{$main_hash{$key}}){ foreach $num2 (0..$#{$main_hash{$key}[$num1]}){ # Now we are far enough down to copy the values $save_hash{$key}[$num1][$num2] = $main_hash{$key}[$num1][$ +num2]; } } } my @save_info; push(@save_info,\%save_hash); push(@save_info,\$aVar); # etc. for all vars to save push(@save_stack,\@save_info); }
    I sure that you will soon get a list of 1001 moduals that do this better.
Re: References and state-saving
by boo_radley (Parson) on Jan 13, 2001 at 03:31 UTC
    Isn't this the kinda thing data::dumper's for?

      Storable makes this much easier than Data::Dumper. Here's a sample using Data::Dumper:
      #!/usr/bin/perl -w use Data::Dumper; my %hash = ('foo' => 'bar', 'camel' => 'beast', 'bug' => 'spray'); #dump the structure open (FILE, '>/tmp/hash') or die "$!\n"; print FILE Dumper(\%hash); close FILE; #recreate the structure open (FILE,'/tmp/hash') or die "$!\n"; my $data = do { local $/; <FILE> }; my %newhash = %{eval $data};
      And here's the same thing with Storable:
      use Storable; store \%hash, '/tmp/hash'; my %newhash = %{retrieve('file')};


      Disclaimer: This post may contain inaccurate information, be habit forming, cause atomic warfare between peaceful countries, speed up male pattern baldness, interfere with your cable reception, exile you from certain third world countries, ruin your marriage, and generally spoil your day. No batteries included, no strings attached, your mileage may vary.
        Here's a sample using Data::Dumper, that doesn't needlessly write the data structure to a temporary file:
        #!/usr/bin/perl -w use Data::Dumper; my %hash = ('foo' => 'bar', 'camel' => 'beast', 'bug' => 'spray'); my %newhash = %{ eval Dumper \%hash };

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://51477]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2017-06-28 04:54 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (624 votes). Check out past polls.