in reply to Two Questions on "my"

A really simple test:

foreach ( 1 .. 10000000 ) { my $i = 1; } print $i, "\n";

Run this test. It will take a few seconds, so don't panic. You'll notice that despite creating $i ten million times, you're not actually using ten million times more memory than had you declared $i outside the loop. This is because $i falls out of scope and gets garbage collected each time the loop iterates. If Perl failed to reclaim that memory, you would start seeing a lot of swapfile activity resulting in hard-drive churning, as your internal memory gets saturated and your operating system begins looking to the swapfile for virtual memory. This isn't happening though, because you're reusing memory.

You'll also notice that you're unable to print $i, after exiting the loop. This also is because $i is no longer in scope, and has been garbage collected.... nothing left to see.


Dave

Replies are listed 'Best First'.
Re: Re: Two Questions on "my"
by Somni (Friar) on May 22, 2004 at 23:00 UTC

    > This is because $i falls out of scope and gets garbage collected each time the loop iterates.

    perl is actually a bit smarter than that. The $i that is used on each iteration is the same $i; the value is simply reinitialized on each iteration.

    You can prove this to yourself by seeing what memory address the scalar has:

    for (1..100) { my $i = 1; print \$i, "\n"; }

    However, this only works as long as the variable would be garbage-collected at the end of scope. If the reference count is higher than 1 at end of scope $i is a whole new scalar on each iteration. Observe:

    for (1..10) { my $i = 1; push(@is, \$i); print "in loop: ", \$i, "\n"; } print "outside loop: $_\n" for @is;