В сценарии жемчуга я пытаюсь принять вход, не блокируясь, и не повторяя вводимые символы (Сценарий производит вывод, и я хочу иметь 'горячие клавиши' для изменения его поведения).
Я добрался до использования
use Term::ReadKey;
ReadMode( "cbreak", STDIN );
if($input = ReadKey($pause_time, STDIN)){
#process input
}
Но после того как пользователь вводит что-либо затем остановки сценария, пока новая строка не вводится. Я хотел бы, чтобы вход был обработан на символ, не ожидая новой строки.
Вот небольшая программа, которая делает то, что, как я думаю, вы хотите:
#!/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;
}
Я собирался оставить это как комментарий к вашему собственному «ответу», но решил, что мне нужно больше места.
cbreak эквивалентен необработанному режиму, за исключением того, что cbreak не перехватывает управляющие последовательности, такие как ctrl-c, ctrl-z и т. Д. Они оба собирают символы по одному. Разница в поведении между двумя режимами не является источником вашей проблемы. Если решение Часа делает что-то похожее на то, что вы планировали, то проблема, скорее всего, связана с тем, что вы отредактировали в строке #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
и запутывая веревку).