epistosaurus
epistosaurus

Reputation: 15

explicit hash dereference vs arrow difference

Consider simple Hash of Hash references. When I derefence the (inside) hash and change some of its value, this does not transfer over to the original hash of hashes. But with arrow notation it does. Everywhere I checked arrow notation is explained as simply a shortcut, so what gives?

use Data::Dumper;

$HoH{"one"}={'f1' => "junk",
      'f2' => 0};

$href = $HoH{"one"};
%hh=%{$HoH{"one"}};

print Dumper($href);

$href->{'f2'}=1;
$href->{'f1'}="newJunk";

print Dumper($HoH{"one"});

$hh{'f2'}=0;
$hh{'f1'}="oldJunk";

print Dumper($HoH{"one"});

Upvotes: 1

Views: 236

Answers (2)

ikegami
ikegami

Reputation: 386541

There are three hashes in your code.

  1. The anon one created by {}. (I shall call it %anon from now on)
  2. %HoH
  3. %hh

$HoH{"one"}={'f1' => "junk",'f2' => 0};
                            # $HoH{one} holds a ref to %anon

$href = $HoH{"one"};        # Copy the ref. $href holds a ref to %anon
%hh=%{$HoH{"one"}};         # Copy the hash referenced by $HoH{one} (i.e. %anon)

print Dumper($href);        # Dumps the hash referenced by $href (i.e. %anon)

$href->{'f2'}=1;            # Modifies the hash referenced by $href (i.e. %anon)
$href->{'f1'}="newJunk";    # Modifies the hash referenced by $href (i.e. %anon)

print Dumper($HoH{"one"});  # Dumps the hash referenced by $HoH{one} (i.e. %anon)

$hh{'f2'}=0;                # Modifies %hh
$hh{'f1'}="oldJunk";        # Modifies %hh

print Dumper($HoH{"one"});  # Dumps the hash referenced by $HoH{one} (i.e. %anon)

Why would modifying %hh affect %anon?

Upvotes: 2

amon
amon

Reputation: 57640

This line does a copy:

%hh=%{$HoH{"one"}};

After that, the changes to the hash %hh are not reflected in the hashref $HoH{one}.

Especially, the above line is a form of list assignment, which performs a copy. No hash references are passed around, as is the case with

$href = $HoH{"one"};

Upvotes: 5

Related Questions