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

I have looked over perl data type's and I have done a blanket Super Search for hashes, but I came up with nothing.

Here is the code:

use Data::Dumper; my %h; # intial hash # put in some random values $h{'a'}{'1'} = 'z'; $h{'a'}{'2'} = 'y'; $h{'a'}{'3'} = 'x'; $h{'b'}{'4'} = 'w'; $h{'b'}{'5'} = 'u'; $h{'b'}{'6'} = 'v'; $h{'c'}{'7'} = 'r'; $h{'c'}{'8'} = 's'; $h{'c'}{'9'} = 't'; # make an assignment that I assume is by value my %tmpHash = %h; # make a change in the temp hash $tmpHash{'b'}{'6'} = 'j'; print Dumper(%h); print "\n\n\n"; print Dumper(%x);
This ends up outputting:

$VAR1 = 'a';
$VAR2 = {
          1 => 'z',
          2 => 'y',
          3 => 'x'
        };
$VAR3 = 'b';
$VAR4 = {
          4 => 'w',
          5 => 'u',
          6 => 'j'
        };
$VAR5 = 'c';
$VAR6 = {
          8 => 's',
          9 => 't',
          7 => 'r'
        };



$VAR1 = 'a';
$VAR2 = {
          1 => 'z',
          2 => 'y',
          3 => 'x'
        };
$VAR3 = 'b';
$VAR4 = {
          4 => 'w',
          5 => 'u',
          6 => 'j'
        };
$VAR5 = 'c';
$VAR6 = {
          8 => 's',
          9 => 't',
          7 => 'r'
        };
As you can see, both hashes are changed. That surprised me. So, I am wondering how do you copy a hash by value. Is a foreach loop the only way to do it?

Jeremy

Replies are listed 'Best First'.
Re: Assigning Hash To Another Hash References Same Hash
by Masem (Monsignor) on Nov 16, 2001 at 01:24 UTC
    You need to use Clone to do a complete copy of a deep hash. Hash assignment only 'clones' the first level, thus copying references directly instead of following them, and thus you get the output as you see.

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important

Re: Assigning Hash To Another Hash References Same Hash
by davorg (Chancellor) on Nov 16, 2001 at 13:59 UTC

    To explain what's going on here...

    Your assignment %tmpHash = %h does copy by value as you assume. The problem is that the values in your hash are actually references to other hashes. Therefore when you alter something at second level of the data structure (as your example does) it's actually the same "second-level" hash that gets updated.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you don't talk about Perl club."

Re: Assigning Hash To Another Hash References Same Hash
by chipmunk (Parson) on Nov 16, 2001 at 07:34 UTC