Reputation: 29
my %hash1 = ( a => 1, b => 2, c => 3 ); my %hash2 = ( a => 1, b => 2, c => 3 ); my $hash_ref1 = \%hash1; my $hash_ref2 = \%hash2;
how the perl compiler creates two distinct hash reference in the memory even the key value pairs are same for both hashes?
Upvotes: 0
Views: 58
Reputation: 386331
Quite simply, my
creates a new variable when executed.
Maybe you think ( ... )
creates the hash. It does not. The parens are simply there to change precedence, like in mathematics. a => 1, b => 2, c => 3
simply puts 6 scalars on the stack, to be assigned to the hash created by my
.
my %h;
is analogous to Hash h = new Hash();
in another language.
use Data::Printer;
my @a; # Creates an array.
for ( 1..3 ) {
my %h = ( id => "x$_" ); # Creates a hash (each time).
push @a, \%h;
}
p @a;
Output:
[
[0] {
id "x1"
},
[1] {
id "x2"
},
[2] {
id "x3"
}
]
Internally, Perl has a number of optimizations to avoid having to create and destroy so many variables. The above actually describes the behaviour you should be observing rather than what actually happens.
Internal details:
my
actually creates the variable at compile time. When executed, it pushes a special instruction on the stack. When the scope is exited, this special instructions causes the variable to be cleared (in the same manner that $s=undef;
, @a=();
and %h=();
would) rather than destroyed. If the reference count indicates the variable is still being used, a new scalar/array/hash is created instead. Yes, that means that my
causes variables to be created on scope exit.
sub f {
# When compiled, creates a scalar.
# When executed, stacks instruction to clear $x.
my $x = shift;
# After copying $x on the stack,
# this simply clears $x instead of destroying it.
return $x;
}
sub g {
# When compiled, creates a scalar.
# When executed, stacks instruction to clear $y.
my $y = shift;
# After creating a reference to $y on the stack,
# this creates a new scalar for $y since
# that scalar is still being referenced.
# The old scalar for $y will get destroyed
# once all remaining references to it are released.
return \$y;
}
Upvotes: 3