Ввод данных оператором <>

В другом способе получения входных данных применяется оператор <>. Он особенно полезен при создании программ, использующих аргументы вызова по аналогии со стандартными утилитами UNIX. Если вы хотите написать программу Perl, которая может использоваться в сочетании с cat, sed, awk, sort, grep, lpr и другими программами, оператор <> будет вашим другом. Если нужно что-то другое, оператор <>, скорее всего, не поможет. Аргументами вызова программы обычно называют «слова», следующие в командной строке после имени программы. В следующей команде они содержат имена файлов, последовательно обрабатываемых вашей программой:

$ ./my_program fred barney betty

Команда запускает программу my_program (находящуюся в текущем каталоге) и приказывает ей обработать сначала файл fred, за ним файл barney, а после файл betty. Если при вызове аргументы не передаются, программа должна обработать стандартный поток ввода. Или в особом случае, если в одном из аргументов передается дефис (-), он тоже означает стандартный ввод. Таким образом, если при вызове программы передаются аргументы fred - betty, подразумевается, что программа должна сначала обработать файл fred, затем стандартный поток ввода, а после него файл betty.


Почему стоит соблюдать эти соглашения в программах? Потому что вы сможете выбрать, откуда программа должна получать входные данные, во время выполнения; например, вам не придется переписывать программу, чтобы использовать ее в конвейере (об этом чуть позже). Ларри включил эту возможность в Perl, потому что он хотел упростить написание программ, работающих в стиле стандартных утилит UNIX, даже в других системах.

Вообще-то он сделал это для того, что-бы его собственные программы работали как стандартные утилиты UNIX. Так как реализации некоторых разработчиков не следуют общим правилам, Ларри может написать собственные утилиты, установить их на разных компьютерах и быть уверенным в том, что они будут работать одинаково. Конечно, для этого необходимо портировать Perl для всех компьютеров, с которыми он собирается работать. Оператор <> в действительности является особой разновидностью оператора построчного ввода. Но вместо того чтобы получать входные данные с клавиатуры, он берет их из источников, выбранных пользователем:

while (defined($line = <>)) {
chomp($line);
print "It was $line that I saw!\n";
}

Таким образом, если запустить эту программу с аргументами fred, barney и betty, она выдаст сообщение: «It was [строка из файла fred] that I saw!», «It was [следующая строка из файла fred] that I saw!» и т.


д., пока не дойдет до конца файла fred. После этого программа автоматически перейдет к файлу barney, последовательно выведет его строки и проделает то же с файлом betty. Обратите внимание на «бесперебойные» переходы от одного файла к другому; при использовании оператора <> все выглядит так, словно входные файлы объединены в один большой файл. Оператор <> возвращает undef (что приводит к выходу из цикла while) только в конце всех входных данных. В данном случае мы имеем дело с особой разновидностью оператора построчного ввода, поэтому можем использовать уже знакомое сокращение для чтения ввода в $_ по умолчанию:

while (<>) {
chomp;
print "It was $_ that I saw!\n";
}

Эта конструкция работает так же, как предыдущий цикл, но занимает меньше места. Также обратите внимание на вызов chomp без аргумента; раз аргумент не указан, по умолчанию chomp применяется к $_. Экономия вроде бы небольшая, а приятно! Поскольку оператор <> чаще всего применяется для обработки всего ввода, обычно его не рекомендуется использовать более чем в одном месте программы. Если окажется, что вы размещаете два оператора <> в одной программе (а особенно если второй оператор находится внутри цикла while, обрабатывающего данные из первого), программа почти наверняка работает не так, как вы ожидаете.


По нашему опыту обычно оказывалось, что когда новички вставляют в программу второй оператор <>, они имеют в виду $_. Помните: оператор <> читает данные, но сами данные (по умолчанию) оказываются в $_.

Если оператор <> не может открыть один из файлов и прочитать данные из него, он выводит (вроде бы) полезное диагностическое сообщение вида

can't open wimla: No such file or directory

После этого оператор <> автоматически переходит к следующему файлу. Именно такое поведение обычно характерно для cat или другой стандартной утилиты.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Perl на эту тему:
Аргументы вызова
Вывод функцией say
Закрытие файлового дескриптора
Запись данных в стандартный вывод
Изменение файлового дескриптора вывода по умолчанию

Вернуться в раздел: Perl / 4. Ввод и вывод