Raghul
Raghul

Reputation: 29

How hash references are created uniquely each time in perl?

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

Answers (1)

ikegami
ikegami

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

Related Questions