简体   繁体   中英

Why isn't this simple Perl push/pop program working?

I'm reading the Llama ( Learning Perl ) book, and working on the exercises. And for this exercise:

Write a program that reads a list of strings on separate lines until end-of-input and prints out the list in reverse order. [. . .]

Well, I already figured out a simpler approach (I remembered you could use reverse on arrays... Perl is so... awesome so far), but I am wondering why this one isn't working.

#!/usr/bin/perl

use 5.010;

chomp(@strings = <STDIN>);

foreach (@strings){
    push @revstrings, $_;
}

while($i++ <= scalar @revstrings){
    say pop @revstrings;
}

It goes like this:

$ ./first
one
two
three
[^D]
three
two
$

the output is the same if I change the <= in the while loop to just < .

You'll never get past halfway... Each time through that last iteration, you'd get:

  • $i++ means that $i will increase by one;
  • pop @revstrings will mean that scalar @revstrings will decrease by one.

They'll meet in the middle, when $i++ just exceeds half the original @revstrings length.

Actually, the $i++ is unnecessary, since scalar @revstrings will be zero when the array is empty, so you just need:

while(scalar @revstrings){
    say pop @revstrings;
}

EDIT : Short answer is "Because your loop condition is wrong." more verbose "scalar @revstrings is evaluated each iteration".

while (<STDIN>) {
    push @lines, $_
}

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

less typing

@lines = <STDIN>;

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

lesser typing

@lines = <STDIN>;
print reverse @lines;

lesser typing

print reverse <>;

but far best solution is

exec("tac");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM