Reputation: 1241
I wonder if this is possible and how: I have a hash of hashes %backup
and I want to save it in a value of another hash of hashes, like this:
$globsessions{$session}{'backup'} = %backup;
and later on (of course) I want it back like this:
%backup = $globsessions{$session}{'backup'};
This is not working and I just lost a little here (maybe to less coffee...). The %globsessions
is global in my app and should be reused.
Many thanks in advance for your help!
Edit:
Using references as Neil suggested does not work, since the child owning %backup
is dead the next time I need the data thus the reference is not valid anymore. So I have more a child/parent problem than a 'copy a hashofhashes' problem. But the solution from Neil for that is properly!
Upvotes: 3
Views: 1265
Reputation: 27207
You have close to the right syntax, but cannot assign a hash directly as a value in another hash. Hash values are scalars. So you need to turn your %backup
into a reference.
If you want to copy the data into the new location:
$globsessions{$session}{'backup'} = { %backup };
This is a shallow copy of contents of %backup
- it is less efficient, but prevents over-writing keys or values in the original variable. Caveat: It doesn't copy deep structures, so if a value in %backup
is another hash or array reference, then it could be modified. Use Storable's dclone
if you want to make a deep copy.
If you want to maintain a reference back to the original hash:
$globsessions{$session}{'backup'} = \%backup;
This stores a reference to %backup
- it is more efficient, but if you set $globsessions{$session}{'backup'}{'foo'} = 'bar'
then you also change the original %backup
To copy data back to %backup:
A shallow copy will probably suffice:
%backup = %{ $globsessions{$session}{'backup'} };
Or using a deep copy, which is slower but safer with data, and requires Storable
:
%backup = %{ dclone( $globsessions{$session}{'backup'} ) };
Upvotes: 7
Reputation: 126742
I suggest you use the Clone
module to duplicate the hash of hashes.
You need to dereference the stored data to move it back to a hash, but it would be more efficient to work with the stored reference.
Like this
use strict;
use warnings;
use Clone 'clone';
$globsessions{$session}{backup} = clone(\%backup);
then retrieve it using
my $backup = $globsessions{$session}{backup}
or, less efficiently, you can replicate the top-level hash elements using
my %backup = %{ $globsessions{$session}{backup} }
or, if you need another complete separate copy that you can modify without affecting the backup in %globsessions
my %backup = %{ clone($globsessions{$session}{backup}) }
Note that these code fragments are untested as I have no access to a Perl compiler at the moment.
Upvotes: 2