Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it good to use my with loops in Perl?

Tags:

perl

I have seen many piece of code in many standard books where my is being used in loops like below.

TYPE 1-

foreach my $mykey ( keys %myhash) {
......
}

or

while(my $line = <$filehandle> ) {
.....
}

Here we are declaring variable for each key of the hash or for each line.Is it a good idea?

In C/C++/Java we used to declare the variable first then we use it. So if I follow that policy then above code should be as below.

TYPE 2-

my $mykey;
foreach $mykey (keys %myhash) {
....
}

or

my $line;
while($line = <$filehandle> ) {
....
}

It will speedup the code execution( I think) because as per context we decide what type of operation can be applied on variable and what will be its behavior.

But I have seen TYPE 1 code mostly in Perl. So I think I am missing some perl concept. Someone please throw light on it.

If you are going to say that it is declared/associated to scope once and then incremented only then please provide some documentation. I could not get it anywhere. I understand that scope of the variable will be different in both the cases.

@http://perldoc.perl.org/perlsub.html#Private-Variables-via-my%28%29-- The my operator declares the listed variables to be lexically confined to the enclosing block, conditional (if/unless/elsif/else), loop (for/foreach/while/until/continue), subroutine, eval, or do/require/use'd file.

will variable association using my will be done in each step?

like image 782
Gaurav Pant Avatar asked Sep 23 '13 05:09

Gaurav Pant


2 Answers

First of all, the biggest difference between

while(my $line = <$filehandle> ) {
.....
}

and

my $line 
while($line = <$filehandle> ) {
.....
}

lies in scope, much more than optimisation for speed or execution time.

In the first case, $line is only visible in the while loop. After that, it goes out of scope, you get your memory back, and you have less chance for mistakes (by using a $line later and not getting an error.

Source: see this perldoc about for loops.

like image 106
Konerak Avatar answered Oct 23 '22 10:10

Konerak


Here is a benchmark:

#!/usr/bin/perl 
use strict;
use warnings;
use Benchmark qw(:all);

my @list = ('abc')x1_000_000;

my $count = -2;
cmpthese($count, {
    'inside' => sub {
        for my $elem(@list) { $elem = '' }
    },
    'outside' => sub {
        my $elem;
        for $elem(@list) { $elem = '' }
    },
});

Result:

          Rate outside  inside
outside 14.3/s      --      0%
inside  14.3/s      0%      --

As you can see, there're no differences in term of speed.

like image 7
Toto Avatar answered Oct 23 '22 09:10

Toto