Hello, I'm fairly new to PERL and this is my first post - so be kind.

I'm working through a book called Beginning PERL for Bioinformatics, and one of the exercises asks to "Write a program to read a file, and then print its lines in reverse order, the last line first".

I've solved the problem, but something kept happening that I didn't understand. When I used this:

#!/usr/bin/perl -w
#Exercise 4.7.

#Assign filename to $filename variable.
$filename = 'list.txt';

#Open file and assign filehandle.
open(LISTFILE, $filename);

#Read file into array.
@filearray = <LISTFILE>;

#Close the file.
close LISTFILE;

#Assign the length of the array to scalar variable.
$a = @filearray;

#Initialise $count variable.
$count = 0;

#Loops through array and pops off the last item and prints it.
while($a > $count)
    {$count++;
	$item1 = pop @filearray;
	print $item1;
   }

exit;

it did the job of reversing my list, but kept putting the last item in my list directly next to the second to last item, but those that followed where on new lines. Sorry that I'm not explaining it too well, here is what I mean.

If my list contains the words:

dog
onion
treaty
frogs
fish

when I reverse it, I get

fishfrogs
treaty
onion
dog

I solved the problem using:

#!/usr/bin/perl -w
#Exercise 4.7.

#Assign filename to $filename variable.
$filename = 'list.txt';

#Open file and assign filehandle.
open(LISTFILE, $filename);

#Read file into array.
@filearray = <LISTFILE>;

#Close the file.
close LISTFILE;

#Assign the length of the array to scalar variable.
$a = @filearray;

#Initialise $count variable.
$count = 0;

#Loops through array popping off the last item and printing it.
#If statement solves the problem with the first two items.
while($a > $count)
    {$count++;
	$item1 = pop @filearray;
	if ($count == 1)
	{
		print $item1, "\n";
	}
	else {
		print $item1;
	}
    }

exit;

but I would like to know what causes the problem with the first two items on the list. I had the same problem when I just reversed the array and assigned it to a new array.

Thanks for any help you can give!

OK, now the easy way......

open(LISTFILE, $filename);
@filearray = <LISTFILE>;
close LISTFILE;
print "$_\n" for reverse @filearray;

Thanks very much, Kevin. I suspect I'll be doing things the hard way until I've written a few more PERL programs.

Still, even your more elegant script seems to be having a slightly different effect on the first two items it deals with. So, using the list from my question, I now get:

fish
frogs

treaty

onion

dog

It gives a blank line after all the items, except fish and frogs. I know it isn't really a big deal, I'm just curious why.

We are adding a newline to the output when the lines of the file already have a newline at the end so we create double-spacing for any line that already has a new line. Sometimes the last line of a file does not have a newline on the end so if you print it in reverse order the first and second lines (of the reversed order) appear to be on the same line. The safest thing to do is use chomp() and print the newline during the output.

open(LISTFILE, $filename);
@filearray = <LISTFILE>;
chomp @filearray;
close LISTFILE;
print "$_\n" for reverse @filearray;
\

Ah, I understand now.

Thanks for your answer to my problem and your improvement of my code, Kevin!

This article has been dead for over six months. Start a new discussion instead.