Term :: ReadKey внутри цикла останавливает вмещающий цикл - PullRequest
1 голос
/ 11 октября 2011

У меня есть цикл while, который работает. Я хочу захватить нажатия клавиш в этом цикле, но процедура ReadKey останавливает вмещающий цикл. Что я делаю не так?

#!/usr/bin/perl

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

my $char;

while(1 < 5) {
    print time . "\n";

    while(1) {
        ReadMode('raw');
        $char = ReadKey(0);
        print "Got $char\n";
    }
    sleep(5);
}

1 Ответ

1 голос
/ 11 октября 2011

Из вашего вопроса и кода, который вы опубликовали, не совсем понятно, что вы пытаетесь выполнить. С одной стороны, вопрос звучит так, как будто вы пытаетесь получить неблокирующее чтение. Если это так, вы можете захотеть что-то еще для своего внутреннего цикла:

while(1) {
    ReadMode('cbreak');
    my $char = ReadKey(-1);
    next unless defined($char);
    print "Got $char\n";
    last if $char eq "\t";
}

ReadKey (-1) устанавливает неблокирующее чтение, что означает, что оно не ожидает ввода; он просто сообщает вам, что представляет собой ввод, если он есть, и затем переходит к следующей итерации. Если нет ввода, он возвращает undef. Вы заметите, что я переключил ReadMode на 'cbreak', для целей тестирования, чтобы я мог легко нажать CTRL-C, когда я был готов завершить работу. Попадание на вкладку также заканчивается в этом примере кода. Поскольку ReadMode () имеет значение -1, для неблокирования мы просто продолжаем цикл.

Ваш код также имел проблему "while( 1 < 5 )". Как вы думаете, что хорошего это для вас делает? 1 всегда меньше 5, поэтому цикл никогда не завершится. Если вы действительно хотите бесконечный цикл, просто скажите while(1), чтобы мы знали, что вы знаете, что вы имеете в виду. С другой стороны, я рассмотрел возможность того, что вы действительно хотели сказать что-то вроде while( $i++ < 5 ), чтобы получить как минимум пять итераций внешнего цикла.

Последнее замечание. Какой бы режим чтения вы ни установили, вам действительно следует вызвать «ReadMode('restore')» перед выходом из программы, иначе ваш терминал может остаться «тупым». Например, на моем, без добавления ReadMode('restore'); в конце программы, нажатие Enter не даст мне новую строку в моем терминале. Похоже, что этот модуль не очищает себя после завершения, поэтому вы должны сделать это явно.

Вам также следует просмотреть документацию для Term :: ReadKey . Большая часть того, что я здесь обсуждал, предназначена для чтения, если вы посмотрите.

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