Perl Term :: ReadKey не ждите новой строки - PullRequest
7 голосов
/ 16 июня 2010

В Perl-скрипте я пытаюсь принять ввод без блокировки и повторения введенных символов (скрипт выводит, и я хочу иметь «горячие клавиши» для изменения его поведения).

Iдошло до использования

use Term::ReadKey;
ReadMode( "cbreak", STDIN );
if($input = ReadKey($pause_time, STDIN)){
    #process input
}

Но как только пользователь что-нибудь наберет, скрипт останавливается до ввода новой строки.Я хотел бы, чтобы ввод обрабатывался для каждого символа, не дожидаясь перевода строки.

Ответы [ 2 ]

7 голосов
/ 16 июня 2010

Вот небольшая программа, которая делает то, что я думаю, что вы хотите:

#!/usr/bin/perl

use strict;
use warnings;

use Term::ReadKey;

ReadMode 4;
END { ReadMode 0 }

print <<EOS;
q to quit
b to print in binary
o to print in octal
d to print in decimal
x to print in hexadecimal
EOS

my $control = "d";
my $i       = 0;
while (1) {
    #use "if" if you want to have a buffer of commands
    #that will be processed one per second  
    while (defined (my $key = ReadKey(-1))) {
        exit 0          if $key eq 'q';
        $control = $key if $key =~ /^[bodx]$/;
    }
    printf "%$control\n", $i++;
    sleep 1;
}
2 голосов
/ 19 июня 2010

Я собирался оставить это как комментарий к вашему собственному «ответу», но решил, что мне нужно больше места.

cbreak эквивалентен режиму raw, за исключением того, что cbreak не перехватывает управляющие последовательности, такие как ctrl-c, ctrl-z и т. Д. Они оба собирают символы по одному за раз. Разница в поведении между двумя режимами не является источником вашей проблемы. Если решение Chas делает что-то похожее на то, что вы намеревались, то проблема, скорее всего, связана с тем, что вы отредактировали в своей строке #process input. Я уже прокомментировал, что ваш оригинальный сценарий работает нормально, если я заполняю его чем-то рудиментарным, чтобы я мог видеть, что он работает. Например, незначительный штрих:

use strict;
use warnings;
use Term::ReadKey;

my ($char, $input, $pause_time);
ReadMode("cbreak");

# Collect all characters typed into $input
# and quit when '#' is typed.

$input = '';
while ($char = ReadKey($pause_time)) {
    last if $char eq '#';
    $input .= $char;
}

print "$input\n";

Мне не нужно нажимать «enter» в конце этого, и это ничего не даст (кроме броска каретки в $input и выветривания строки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...