Перебор строки в Perl

#string #perl #for-loop

#строка #perl #for-цикл

Вопрос:

Я хочу создать скрипт, который будет вводить строковые буквы одну за другой

 my $str = 'Test String';
my @spl = split '',$str;
for (@spl){
    print "$_";
    sleep(1);
}
print "n";
 

sleep() не выполняет свою работу! это заставляет меня ждать более 1 секунды, и я получаю полный текст немедленно без каких-либо задержек.

Комментарии:

1. Переход в спящий режим может занять не всю секунду — прочитайте руководство

Ответ №1:

В вашем цикле вы выводите только 2 элемента. Существует также тот факт, что ваш вывод может быть буферизован, и поэтому буфер может быть очищен и распечатан только при n отправке.

Попробуйте установить $| ненулевое значение, которое может отключить буферизацию строк.

например

 $| = 1; 
$|  ; // alternative often seen
 

В качестве альтернативы, это делает то же самое:

 STDOUT->autoflush(1);    # Needs "use IO::Handle;" on older versions of Perl
 

Хотя, вероятно, проблема здесь не в этом, sleep() это не лучший способ подождать секунду, особенно в старых системах. Как указано в руководстве, существуют причины, по которым переход в режим ожидания может занимать менее или более 1 секунды.

Комментарии:

1. В этом случае выполнение sleep(1) вызова, вероятно, занимает очень близко к 1 секунде. Это отличный способ подождать в современных системах. Проблема здесь в буферизации вывода.

2. Согласен, я отредактировал свой ответ, чтобы немного преуменьшить этот аспект, но я все же думаю, что об этом следует упомянуть.

3. Я бы поддержал этот вариант, если бы вы использовали более современный и мгновенно более понятный STDOUT->autoflush(1) ; попробуйте использовать этот вместо него.

4. @LeoNerd TMTOWTDI — должен прекратить участвовать в запутанных соревнованиях PERL 🙂

Ответ №2:

Поместить

 use IO::Handle;
STDOUT->autoflush();
 

перед печатью отключите буферизацию вывода (и, следовательно, ожидайте сначала заполнения буфера).

Ответ №3:

Вы страдаете от буферизации. Предоставленная ссылка приведет вас к отличной статье Марка Джейсона Доминуса (автора Perl более высокого порядка), опубликованной в Perl Journal примерно в 1998 году. Статье может быть более десяти лет, но тема так же актуальна сегодня, как и тогда, когда он ее писал.

В вашем случае вам нужно сделать

 {
    local $| = 1;
    for (@spl){
         print "$_";
         sleep(1);
    }
}
 

или используйте IO::Handle , как предложил mpapec.