5

I'm working with hashes in perl, but don't understand why the hash value changes in the following:

use strict;

sub test
{
    my ($value_ref) = @_;
    my %value = %$value_ref;
    $value{'abc'}{'xyz'} = 1;
}

my %hash;
$hash{'abc'}{'xyz'} = 0;
test (\%hash);
print "$hash{'abc'}{'xyz'}\n";

The above returns 1, why doesn't it return 0 like this it does here?

use strict;

sub test
{
    my ($value_ref) = @_;
    my %value = %$value_ref;
    $value{'abc'} = 1;
}

my %hash;
$hash{'abc'} = 0;
test (\%hash);
print "$hash{'abc'}\n";

I imagine it has to do with how I'm passing in %hash. What am I missing?

2 Answers 2

7

You are getting incorrect results because when you make your copy of the hash using my %value = %$value_ref; you are only getting the top-level keys. The second level, with the key 'xyz', is the one where value is actually stored so any changes to that reference are carried over. You are performing a shallow copy when you need a deep copy.

Luckily there is a CPAN module for that!

use strict;
use Storable qw(dclone);

sub test
{
    my ($value_ref) = @_;
    my %value = %{ dclone($value_ref) };
    $value{'abc'}{'xyz'} = 1;
}

my %hash;
$hash{'abc'}{'xyz'} = 0;
test (\%hash);
print "$hash{'abc'}{'xyz'}\n"; # prints 0
Sign up to request clarification or add additional context in comments.

2 Comments

How do I make the top-level keys to be reference too?
3

This is because the "second level" of your hash (IOW: the value for key 'abc') is itself a hash reference. While you're copying the contents of the hash referenced by $value_ref in your assignment:

my %value = %$value_ref;

...this is only doing a "shallow" copy.

When you modify the value for key 'xyz', you're modifying the same hash that is in the original structure passed to the sub.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.