Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a simple tac program

Tags:

perl

I was trying to solve an exercise in "Learning Perl" by Schwartz, when I happened across an unexpected output in the code I wrote. I was wondering what I've done wrong.

Qn: Implement a simple tac similiar to the unix utility.

My solution:

#!/usr/bin/perl
use strict;
use warnings;

my @array;
while (<>) {
    push @array, $_;
}

foreach ($#array..0) {
    print $array[$_];
}

Implementing it with: $ ./tac list

where list contains:

$ cat list 
An apple 
Blue boys
Coy cows
Dreary ducks!

gives no output.

$ ./tac list
$
like image 669
Joel G Mathew Avatar asked Mar 20 '23 12:03

Joel G Mathew


2 Answers

Your problem is the foreach loop counter. You can't go backwards like that.

You could instead do:

while (@array) {
    print pop @array;
}

or just:

print pop @array while (@array);

while (@array) will evaluate @array in a scalar context, which means that the size of the array will be tested. When the size reaches zero, the loop will terminate.


As this is perl, there are of course a million ways to do this. Another would be:

print for reverse @array

...or you could read in the array backwards by using unshift:

#!/usr/bin/perl
use strict;
use warnings;

my @array;
while (<>) {
    unshift @array, $_;
}

print for @array;

...or you could even just do:

#!/usr/bin/perl
use strict;
use warnings;

print reverse <>;

Enjoy learning Perl!

like image 89
Tom Fenech Avatar answered Mar 27 '23 17:03

Tom Fenech


The range notation doesn't count down:

$ perl -e 'foreach my $i (10..0) { print "$i\n"; }'
$

You can use:

#!/usr/bin/perl
use strict;
use warnings;

my @array = <>;

foreach (0..$#array)
{
    print $array[$#array - $_];
}
like image 39
Jonathan Leffler Avatar answered Mar 27 '23 18:03

Jonathan Leffler