perl - Using same hash, why is data not overwritten after hash ref assigned? -
i have written routine builds complex data structure using hashes.
use strict; %th1 = (); %th2 = (); $idx = 0; $th2{"suffix"} = "a"; $th2{"status"} = 0; $th2{"consumption"} = 42; $th1{$idx} = \%th2; $idx++; $th2{"suffix"} = "b"; $th2{"status"} = 0; $th2{"consumption"} = 105; $th1{$idx} = \%th2; $key1 (keys %th1) { $key2 (keys %{$th1{$key1}}) { print "key1=$key1, key2=$key2, value=" . $th1{$key1}->{$key2} . "\n\n"; } }
my question is, when hash reference assigned, why isn't first set of data @ $idx == 0
corrupted?
has there been copy created when hash ref assigned $th1{$idx} = \%th2;
?
when line executed
$th2{"suffix"} = "b";
why aren't hash values @ $th1{0}
corrupted?
the values not corrupted, i'm curious mechanism preserves these values. code has not explicitly created new copy of %th2
. so, going on behind scenes?
the output of program is:
key1=1, key2=status, value=0 key1=1, key2=suffix, value=b key1=1, key2=consumption, value=105 key1=0, key2=status, value=0 key1=0, key2=suffix, value=b key1=0, key2=consumption, value=105
if see different when run it, please indicate see.
there no corruption, nor copying being done. %th1
contains pointers single other hash.
there 1 hash @ 1 memory location, , hash @ another. modify %th2
, changes.
modifying little bit can have more compact output , able call display function.
#!/usr/bin/perl %th1 = (); %th2 = (); $th2{"suffix"} = "a"; $th2{"status"} = 0; $th2{"consumption"} = 42; $th1{0} = \%th2; print "--- after first block:\n"; display(\%th1); $th2{"suffix"} = "b"; print "--- modified th2 suffix b:\n"; display(\%th1); $th2{"status"} = 0; $th2{"consumption"} = 105; print "--- finished modification of th2:\n"; display(\%th1); $th1{1} = \%th2; print "--- after assignment th1{1} :\n"; display(\%th1); exit; sub display { $hr = shift; $key1 (keys %$hr) { print "$key1:\n"; $key2 (keys %{$hr->{$key1}}) { print "\t$key2 = $hr->{$key1}{$key2}\n"; } } }
the output of is:
--- after first block: 0: status = 0 suffix = consumption = 42 --- modified th2 suffix b: 0: status = 0 suffix = b consumption = 42 --- finished modification of th2: 0: status = 0 suffix = b consumption = 105 --- after assignment th1{1} : 1: status = 0 suffix = b consumption = 105 0: status = 0 suffix = b consumption = 105
you can see modifications %th2
taking effect in dereferenced values in %th1
.
lets @ differently... instead of printing out values, lets print out %th1
contains? 2 changes... addition of line show memory near top:
my %th1 = (); %th2 = (); print \%th1, "\t", \%th2,"\n"; # line added
and display
changed:
sub display { $hr = shift; $key1 (keys %$hr) { print "$key1 --> $hr->{$key1}\n"; } }
now output is:
hash(0x239edb0) hash(0x239edf8) --- after first block: 0 --> hash(0x239edf8) --- modified th2 suffix b: 0 --> hash(0x239edf8) --- finished modification of th2: 0 --> hash(0x239edf8) --- after assignment th1{1} : 1 --> hash(0x239edf8) 0 --> hash(0x239edf8)
the values of %th1
point single hash way through. no copies, 1 hash changed behind of %th1
.
chances are, want separate values @ each spot. done creating anonymous hash , assigning that:
#!/usr/bin/perl %th1 = (); %th2 = (); $th1{0} = {"suffix" => "a", "status" => 0, "consumption" => 42 }; print "--- after first block:\n"; display(\%th1); $th1{1} = {"suffix" => "b", "status" => 0, "consumption" => 105 }; print "--- after assignment th1{1} :\n"; display(\%th1); exit; sub display { $hr = shift; $key1 (keys %$hr) { print "$key1: $hr->{$key1}\n"; $key2 (keys %{$hr->{$key1}}) { print "\t$key2 = $hr->{$key1}{$key2}\n"; } } }
which prints:
--- after first block: 0: hash(0xcf6998) status = 0 suffix = consumption = 42 --- after assignment th1{1} : 1: hash(0xd143c0) status = 0 suffix = b consumption = 105 0: hash(0xcf6998) status = 0 suffix = consumption = 42
you can see 2 separate memory addresses , 2 separate sets of values.
Comments
Post a Comment