Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my Perl loop off by one at the end?

I have this program which does not work as expected. Help me.

I want to print a row heading.

If input is 4, I want 1|2|3|4 to be output.

It does not work as all, if I hard-code $count value it works partially but the last number is missing.

sub printC {
        my $count = @_;
        # count = 4  # works partially only prints 1|2|3
        for(my $i=1;$i<$count;$i++) {
                print "$i|";
        }
        print $i;
}
$count  = 2;
&printC($count);
print "\n";
like image 834
user485167 Avatar asked Oct 23 '10 16:10

user485167


2 Answers

A real Perl hacker might write something like this:

sub printC {
  my $count = shift;
  print join "|", (1 .. $count);
}

Once you understand how this works, you'll find you've learned some more about Perl. :-)

like image 20
Tim Avatar answered Sep 21 '22 23:09

Tim


The problem is here:

my $count = @_;

The assignment is happening in a scalar context which assigns the number of elements in array @_ to $count, which your case is 1, as you are passing 1 argument to the function.

To fix this you can do:

my ($count) = @_; 

or

my $count = $_[0];

here is another problem:

for(my $i=1.....
    ^^

By using my you've made $i local to the body of for and it'll not be available outside it. So your final print outside the for is not printing anything. To fix this move the declaration of $i outside the loop:

sub printC {
        my ($count) = @_;
        my $i;
        ....

Always make it a point to write

use strict;

at the top of your program which enables you to catch such bugs.

The perl way of doing what your function does is:

print join('|',1..$count);
like image 159
codaddict Avatar answered Sep 23 '22 23:09

codaddict