shift and push question in perl

hi,

another perl question,

I don't understand the below

while (<FILE>) {
push @last5, $_; #add to the end
shift @last5 if @last5 > 5 ; #take from the beginning
}

can someone please explain to me how does

shift @last5 if @last5 > 5 is taking last 5 lines from the file?
I am just not getting it,
1) I thought shift was taking item from begining, shouldn't it be the begining of the file?

2) not understanding how shift @last5 if @last5 > 5 works.. can somone let me know item by item please?

big thank you in advance

No, because it is the overall effect of the entire while() loop that causes the last 5 lines to be stored in the @last5 array variable, not due to that shift() function alone.

While each line is added to the array in each iteration, if the "shift() .... if ..." finds that more than 5 (maximum 6, actually) lines stored in the array, it will start removing a single line each time from the top so the count is maintained at 5. You can view this as a circular buffer. Of course, when the loop terminates, the items inside must be the last 5 lines read from the file (or may be less, if the file has < 5 lines).

If you still don't get it, put some print() in the loop to print the loop content in each iteration to see for yourself the change in content in action. Of course you can use debugger. Good only if you know how to use it, and the Perl debugger is, em, well .......

I understand the latter part.. but I still don't understand why

push @last5, $_ ; statment is needed...

main::(tail1.pl:5): open(FILE, '<', 'gettysburg.txt') or die $!;
DB<1> s
main::(tail1.pl:6): my @last5;
DB<1>
main::(tail1.pl:8): while (<FILE>) {
DB<1>
main::(tail1.pl:9): push @last5, $_; # add to the end

I think I understand now.. so basicalli this program goes through the whole file and rebuilds the file adding items (to the end so that first item is in the top)... and it will shift(take items from top) if it has more than 2... did I understand this correctly?

#!/usr/bin/perl -w

use strict;

open(FILE, '<', 'gettysburg.txt') or die $!;
my @last5;

while (<FILE>) {
push @last5, $_; # add to the end
print @last5;
shift @last5 if @last5 > 2; # take from the beginning
print @last5;
}

close FILE;

print "Last five lines:\n", @last5;

main::(tail1.pl:5): open(FILE, '<', 'gettysburg.txt') or die $!;
DB<1> s
main::(tail1.pl:6): my @last5;
DB<1>

1
main::(tail1.pl:9): push @last5, $_; # add to the end
DB<1>
main::(tail1.pl:10): print @last5;
DB<1>
1
2

DB<1>
2
3
main::(tail1.pl:15): close FILE;
DB<1>
main::(tail1.pl:17): print "Last five lines:\n", @last5;
DB<1>
Last five lines:
2
3

Yes, and that was exactly what I explained in my previous reply.

if @last5 > 2;

this forces @last5 into a scalar context,
an @array in a scalar context yields the number of elements,

so
if @last5 > 2;

means if @last5 has > 5 elements

any better?

it's the thing with perl being context sensitive, unlike any other languages I know of.