Ввод-вывод в Perl

1 Июл
2012

Здравствуйте!

Начав читать книгу «Шварц Р., Фой Б., Феникс Т. — Perl. Изучаем глубже. 2-е издание», понял, что немного запутался в способах ввода-вывода Perl. Для этого решил сделать вот-такой конспект, который хочу предложить вашему вниманию.



Работа с аргументами вызова скрипта
Аргументы вызова скрипта заносятся в массив @ARGV, т.е. для следующего вызова

$ perl test.pl lesson1 lesson2 lesson3

массив @ARGV будет содержать qw/lesson1 lesson2 lesson3/.

Работа с массивом @ARGV как с переменной по-умолчанию
С массивом @ARGV можно работать как с переменной по-умолчанию (аналогично $_ или @_).

my $line = shift;

my $line = shift @ARGV;



my $line = pop;

my $line = pop @ARGV;


Эти две пары строк эквивалентны, за одним исключением — версии с аргументом по-умолчанию не должны вызываться внутри подпрограммы, т.к. там имеется своя переменная по-умолчанию — @_. Приведем пример:

use Modern::Perl;

use utf8;



my $arg1 = shift; # по-умолчанию используется массив @ARGV

say «arg1: $arg1»;



my @name_and_arg = get_name_and_arg(„TheAthlete”);

say «(name arg2) = (@name_and_arg)»;



sub get_name_and_arg {

  my $name = shift; # по-умолчанию используется массив @_

  

  my $arg2 = shift @ARGV; # явно используем @ARGV

  return ($name, $arg2);

}


$ perl test.pl hello world
arg1: hello
(name arg2) = (TheAthlete world)
$

На самом деле операция pop выполняется довольно редко.

Чтение данных из стандартного ввода
Получить данные из стандартного потока ввода можно с помощью оператора <STDIN>. Выполнение этого оператора в скалярном контексте дает следующую строку данных:

print «Enter name: »;

my $name = <STDIN>; # Прочитать следующую строку

chomp $name; # Удалить завершитель

say «Name: $name»;


$ perl test.pl
Enter name: Fred
Name: Fred
$

При достижении конца файла (в данном примере это ввод Ctrl+d в Linux или Ctrl+z в Windows вместо ввода имени) оператор построчного вывода возвращает undef. Чтобы было более понятно, этот пример можно переписать следующим способом:

print «Enter name: »;

my $name = <STDIN>; # Прочитать следующую строку

if (defined $name) {

  chomp $name; # Удалить завершитель

  say «Name: $name»;

} else {

  say «Пустая строка ввода»;

}


$ perl test.pl
Enter name: <Ctrl+d> или <Ctrl+z>
Пустая строка ввода
$

Также, это обстоятельство часто используется для выхода из цикла:

my $name;

print «Enter name: »;

while (defined($name = <STDIN>)) {

  chomp $name;

  say «Name: $name»;

}


$ perl test.pl
Enter name: Vasya
Name: Vasya
Petya
Name: Petya
Kolya
Name: Kolya
<Ctrl+d> или <Ctrl+z>
$

Для такой простой ситуации, как эта, есть сокращенная версия:

print «Enter name: »;

while (<STDIN>) {

  chomp;

  say «Name: $_»;

}


Данную версию следует использовать только для простых вариантов. Для более сложных конструкций лучше использовать именованные переменные, а не переменные по-умолчанию.

Оператор построчного ввода может работать также в списочном контексте:

my @names;

print «Enter names: »

chomp(@names = <STDIN>);

say «names: @names»;


$ perl test.pl
Enter names: Fred
Wilma
Kolya
Sanya
names: Fred Wilma Kolya Sanya

Ввод данных оператором <>
Оператор <> является особой разновидностью оператора построчного ввода. Но вместо того, чтобы получать входные данные с клавиатуры, он берет их из источников, выбранных пользователем:

test1.txt
test1 text

test2.txt
test2 text

test3.txt
test3 text

test.pl
use Modern::Perl;

use utf8;



my $line;

while (defined($line = <>)) {

  chomp $line;

  say $line;

}


$ perl test.pl test1.txt test2.txt test3.txt
test1 text
test2 text
test3 text

Как и в случае с оператором построчного ввода, данную программу можно существенно сократить:

use Modern::Perl;

use utf8;

while (<>) {chomp; say;}


Данная программа последовательно проходит каждую строку в каждом файле. При использовании оператора <> все выглядит так, словно входные файлы объединены в один большой файл. Оператор <> возвращает undef (что приводит к выходу из цикла while) только в конце всех входных данных.

Получение списка файлов по шаблону.
Если требуется получить список файлов по шаблону, аналогичному конструкциям *.* (MS-DOS, Windows) и *.h (UNIX), то можно воспользоваться следующей записью:

my @list = <*.c>;

my @list = glob(„*.c”);


Также оператор <> может применяться к файловым дескрипторам, но в этой статье я не буду освещать данную тему.
По материалам Хабрахабр.



загрузка...

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

Наверх