IvyR has asked for the wisdom of the Perl Monks concerning the following question:

This code isn't working for me. All I want to do is read in a string and print it out again until the user types "quit". It reads and prints but never hits true on the while condition. This should be very simple, but I can't figure out what I'm doing wrong. If it helps, I'm using Active Perl 5.12
#!/c:\perl64\bin do { print "Enter an address, QUIT to exit\n"; my $test = <STDIN>; chomp($test); print "$test\n"; } while (lc($test) ne "quit");

Replies are listed 'Best First'.
Re: do-while loop never exits
by Neighbour (Friar) on Apr 19, 2011 at 12:58 UTC
    This is because you're declaring $test inside the loop using my. The consequence of this is that the variable doesn't exist outside the loop (where your while-condition resides). You can fix this by either declaring my $test; before entering the loop, or using something like this to exit instead:
    while (1) { print "Enter an address, QUIT to exit\n"; my $test = <STDIN>; chomp ($test); print "$test\n"; if (lc ($test) eq "quit") { last; } } ## end while (1)
      That did it. Thank you very much.
      This would have been caught if you used strict.
Re: do-while loop never exits
by ww (Archbishop) on Apr 19, 2011 at 13:10 UTC
    $test is out of scope when your code reaches line 8; hence, $test is always ne "quit."

    One way around that is to declare my $test" at (an inserted) line 2 and remove the "my" at line 5; there are other alternatives to making $test global (which is generally a bad idea).

    In any case, in earlier versions of Perl, use strict; use warnings would have alerted you to this problem; since it didn't (or, "Naughty, naughty! You didn't tell us about a message on the order of 'Global symbol "$test" requires explicit package name at ....'"), I'm going to have to recheck my (mis-?) understanding that 5.12 would invoke strict unless overridden see below.

    Update: Credit Corion who offered the necessary correction to my misunderstanding:

    "...the implicit strictures come from use 5.12;"

    brian d foy posted (to http://www.effectiveperlprogramming.com/blog/468) on the subject:

    "Perl 5.12 can turn on strict for you automatically, stealing a feature from Modern::Perl that takes away one line of boilerplate in your Perl programs and modules. We talk about strict in Item 3: Enable strictures to promote better coding. Similar to what we show in Item 2: Enable new Perl features when you need them, to turn strictures on automatically, you have to use use with a version of Perl 5.11.0 or later:

        use 5.012;

    This is really just the same thing as explicitly turning on strict and importing the 5.12 feature bundle:

    use strict; use feature ':5.12';

    Note that this means merely importing the feature bundle does not include this implicit strictures benefit. Don’t think you’re safe merely because you are using a perl5.12 interpreter.

Re: do-while loop never exits
by toolic (Bishop) on Apr 19, 2011 at 13:23 UTC
Re: do-while loop never exits
by CountZero (Bishop) on Apr 19, 2011 at 18:10 UTC
    Or all in one line:
    print while (($_ = <STDIN>) ne "quit\n");

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: do-while loop never exits
by eff_i_g (Curate) on Apr 19, 2011 at 14:17 UTC
Re: do-while loop never exits
by raybies (Chaplain) on Apr 19, 2011 at 13:00 UTC

    I see you're running on a PC. the end of line terminator in windoze is '\r\n', but you may have your end of line terminator set to solely '\n', which would cause it to never quit.

    --Ray

    Also did you type in the first line correctly? Just curious, I don't do the PC perl thing much, but should it have a #!/c: or just a #!c: ?

      ...line terminator set to solely '\n', which would cause it to never quit.

      The PerlIO layer ":crlf" (which is active on Windows by default) translates \r\n to \n, so the chomp with the subsequent eq test would work fine...

        /me hangs his head in shame.