Как читать абзацы одновременно с Perl? - PullRequest
1 голос
/ 27 ноября 2009

Когда я пишу

#!/usr/bin/perl -w
use strict;

while( <DATA> ) {
    print "\n-------------------------\n\n";
    print;
    <>;
}

после каждого «возврата» я получаю одну строку.

Почему я не получаю следующий скрипт после каждого "возврата" одного абзаца?

#!/usr/bin/perl -w
use strict;

local $/ = "";

while( <DATA> ) {
    print "\n-------------------------\n\n";
    print;
    <>;
}

__DATA__
line one
line two
line three
line four
line five

line six
line seven
line eigth
line nine

line ten
line eleven
line twelve

Ответы [ 3 ]

5 голосов
/ 27 ноября 2009

В вашем первом скрипте с переменной $ / variable, установленной по умолчанию "\ n", будет возвращать только одну строку за раз.

Я полагаю, что второй скрипт выполняет то, что вы хотите, просто <> не прекратит чтение при возврате, а скорее при из-за ваших настроек $ / (как кто-то указал <> читает из STDIN, но я думаю, что вы уже знаете это и используете его для регулирования вывода).

Если вы действительно хотите регулировать выход с помощью 'return', вам нужно сделать больше с $ / в цикле.

while( <DATA> ) {
    print "\n-------------------------\n\n";
    print;
    $/ = "\n"; # default so that the following terminates the read on 'return'
    <>;
    $/ = ""; 
}   
3 голосов
/ 27 ноября 2009

Полагаю, вы ожидаете эту строку

local $/ = "";

чтобы изменить поведение

<DATA>

чтобы продолжить чтение до конца данных.

Но на самом деле требуется что-то вроде этого

{
    local $/;  # $/ becomes undef in this block
    ...
}

для включения режима slurp (и для помещения этого режима в область видимости внутри {curlys}).

По сути, он говорит: «забудьте о том, чтобы думать о новых строках как о маркере конца записи»,

Кроме того ... в вашем коде есть боец ​​связи

while( <DATA> ) {
    print "\n-------------------------\n\n";
    print;
    <>;    # <-- Feel the power of the DARK SIDE!!!
}

Этот маленький парень будет читать из STDIN, а не из DATA - это действительно то, что вы хотите?

2 голосов
/ 27 ноября 2009

Использование <> таким образом (в интерактивном режиме) в режиме абзаца может привести к путанице. Он не вернется, когда вы нажмете «вернуться»; вместо этого он будет читать, пока не получит непустую строку (начало абзаца), затем будет читать, пока не получит пустую строку (конец этого абзаца), затем продолжит чтение, пока не получит непустую строку (начало следующего абзаца - который будет буферизован, а не возвращен), поэтому он знает, что он отбрасывает все лишние пустые строки.

Возможно, вы должны использовать:

local $/ = "\n"; <>

в конце цикла. Или, может быть, POSIX :: getchar ().

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