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

Popular posts from this blog

basic authentication with http post params android -

vb.net - Virtual Keyboard commands -

css - Firefox for ubuntu renders wrong colors -