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

I have a problem where i would like a while loop to continue until it receives input from the keyboard. Currently the loop stops and waits for input.
#!/usr/bin/perl use strict; my $done = 0; my $choice; while (! $done) { print "Test\n"; chomp ( $choice = uc (<>)); $done = 1 if ( $choice eq "Q" ) }

Retitled by davido.

Replies are listed 'Best First'.
Re: How do I loop until keyboard input?
by dragonchild (Archbishop) on Dec 15, 2004 at 15:01 UTC
    You need some sort of getc() implementation. I would reccomend using Term::ReadKey. From the example:
    use strict; use Term::ReadKey; ReadMode 4; # Turn off controls keys my $key; while (not defined ($key = ReadKey(-1))) { print "Test\n"; } print "Get key $key\n"; ReadMode 0; # Reset tty mode before exiting

    Modify as needed.

    Update: Fixed per gellyfish's note.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      Modify as needed.

      The first modification needed will be to fix the typo in the while line ;-) I have had this fixed in CVS for a while but haven't released it to CPAN yet.

      Bad maintainer bad bad

      /J\

Re: How do I loop until keyboard input?
by gellyfish (Monsignor) on Dec 15, 2004 at 15:02 UTC

    It is not so easy to do this directly from STDIN, you might be better off using Term::ReadKey:

    use Term::ReadKey; my $done = 0; my $choice; ReadMode 4; while ( !$done ) { if ( defined( $key = ReadKey(-1) ) ) { $choice = uc ( $key); $done = 1 if $choice eq 'Q'; } } + ReadMode 0;

    /J\

      I have tried Readkey but from my experience it is still waiting for input before it continues the loop.
      #!/usr/bin/perl -w use strict; use Term::ReadKey; my $done = 0; my $choice; my $key; ReadMode 4; while (! $done) { if (defined($key = ReadKey(-1))) { print "Test\n"; $choice = uc ($key); $done = 1 if ( $choice eq "Q" ) } } ReadMode 0;

        No it isn't if you have ReadMode 4 set. Of course if you have actually tried the code and it doesn't do what you expect then please can you send me a bug report stating the OS, Term::ReadKey and Perl version and with the exact code that you were trying to use.

        /J\

Re: How do I loop until keyboard input?
by Roy Johnson (Monsignor) on Dec 15, 2004 at 15:47 UTC
    Using select will make your example work the way you seem to expect (type Q [Return] to quit).

    As the other replies note, if you want it to take unbuffered input (i.e., you don't have to press [Return]), you should use Term::ReadKey.

    my $done = 0; my $choice; my $rin = ''; vec($rin, fileno(STDIN), 1) = 1; my $timeout = 0; while (! $done) { print "Test\n"; if (select(my $rout=$rin, '', '', $timeout)) { chomp ( $choice = uc (<>)); $done = 1 if ( $choice eq "Q" ); } }

    Caution: Contents may have been coded under pressure.