Операции ввода данных

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

Операция < >

Для начала работы с файлом в программе Perl его следует открыть с помощью функции open( ). Первым из передаваемых ей фактических параметров является идентификатор, называемый дескриптором файла. Он служит для ссылки на открытый файл непосредственно в самой программе. Операция ввода из файла осуществляется заключением в угловые скобки его дескриптора <дескриптор_файла>. Результатом вычисления этой операции является строка файла или строки файла в зависимости от того, в каком контексте она используется — скалярном или списковом. Следующие операторы иллюстрируют эту особенность данной операции:
ореn(MYFILE, "data.dat");  # Открытие файла "data.dat" и
                           # назначение ему
                           # дескриптора MYFILE 
$firstline = <MYFILE>;     # Чтение первой строки файла и
                           # сохранение в переменной $firstline
                           # (скалярный контекст)
@remainder = <MYFILE>;     # Чтение остальных строк файла и
                           # сохранение их в элементах массива
                           # @remainder (списковый контекст)
Особый случай представляет операция чтения из файла с пустым дескриптором < >: информация считывается либо из стандартного файла ввода, либо из файлов, заданных в командной строке.

Операция «документ здесь»

В Perl реализована интересная возможность «ввода» строковых данных в программу. Она реализует синтаксис «документ здесь» командного интерпретатора shell системы UNIX и позволяет задавать в программе строковые данные большого объема, расположенные в нескольких последовательных строках текста программы, используя их в качестве операндов разнообразных операций: присваивания, печати и т. п. Синтаксис операции прост — после знака операции << задается завершающий идентификатор, который служит признаком конца «вводимой» последовательности строк данных. Семантика этой операции следующая: все строки данных, расположенные между текущей строкой, содержащей операцию «документ здесь» и строкой, содержащей завершающий идентификатор, рассматриваются как одно строковое значение, которое используется в выражении как операнд в том месте, где в нем задана операция «документ здесь»:
$multi_line_string = <<FINISH; 
строка 1 
строка 2
FINISH
В приведенном фрагменте кода в качестве правого операнда операции присваивания используется строка "строка 1\nстрока 2\n", которая и будет присвоена скалярной переменной $multi_line_string. Обратите внимание, что строка данных, «введенная» в программу операцией «документ здесь», содержит управляющие последовательности перехода на новую строку в конце каждой строки исходных данных, определенных в тексте программы. По умолчанию операция «документ здесь» интерпретирует содержимое всех строк исходных данных в программе до завершающего идентификатора как строковые данные, заключенные и двойные кавычки, сохраняя в них символ перехода на новую строку "\n", а также осуществляя подстановку значений переменных и интерпретации управляющих символов.
Однако это не единственно возможный вариант интерпретации вводимых строковых данных. Perl позволяет явно указать, как будут интерпретироваться строковые данные при этой операции, заключив в соответствующие кавычки (одинарные, двойные или обратные) завершающий идентификатор операции. Причем в случае задания завершающего идентификатора без кавычек он должен сразу же следовать за знаком операции << без каких-либо пробелов, тогда как при заключении завершающего идентификатора в кавычки любого типа он может быть отделен от знака операции «документ здесь» любым числом пробельных символов. Следующие две операции «документ здесь» - эквивалентны:
print <<m;  # по умолчанию используются двойные кавычки
line 1
m
print << "m"; # явное использования двойных кавычек
line 1
m
ВНИМАНИЕ В строке, физически ограничивающей данные операции «документ здесь», завершающий идентификатор всегда задается без каких-либо кавычек, должен начинаться с первой позиции и в точности соответствовать его определению в операции <<. Если случайно завершающий идентификатор без кавычек отделен пробелом от знака операции, то будет сгенерирована ошибка о появлении простого слова (bareword) там, где должен быть знак операции. Дело в том, что в операции «документ здесь» можно вообще не задавать завершающего идентификатора, а заменить его пробелом. В этом случае считается, что строки данных этой операции завершаются первой пустой строкой после строки программы, где встретилась эта операция
При задании завершающего идентификатора в кавычках на строковые данные, вводимые операцией «документ здесь», распространяются все правила подстановок переменных и интерпретации управляющих символов, применяемые к строкам, ограниченным соответствующим типом кавычек. Продемонстрируем использование различных типов кавычек в операции «документ здесь»:
$var = "Ларри Уолл";
print <<FIRST;    # Отобразит две строки:
Пользователь:     # Пользователь:
\t$var            #        Ларри Уолл
FIRST

print <<’FIRST’;  # Отобразит две строки:
Пользователь:     # Пользователь:
\t$var            # \t$var  
FIRST
print <<`FIRST`;  # Отобразит две строки:
echo $var               # Ларри Уолл
FIRST
ВНИМАНИЕ В строках данных операции «документ здесь» должна располагаться только та информация, которая требуется для работы программы. Комментарии в них не действуют, а рассматриваются как обычное содержимое соответствующей строки, в которой они определены. В нашем примере мы использовали комментарии исключительно для того, чтобы показать, что будет выведено при выполнении этого сценария. Поэтому при выполнении этого примера самостоятельно следует удалить все комментарии.
Обратите внимание, что в приведенных примерах использовался один завершающий идентификатор FIRST. Подобная практика не приводит к двусмысленностям и ошибкам компиляции, так как компилятор после того, как встретил операцию «документ здесь», ищет первую после нее строку с завершающим идентификатором. Главное, чтобы завершающий идентификатор в строке завершения был задан именно так, как он определен в самой операции, причем с первой позиции строки и без каких-либо комментариев в ней.
ПРИМЕЧАНИЕ При использовании операции «документ здесь» с завершающим идентификатором в обратных кавычках в некоторых операционных системах может возникнуть проблема с обработкой потока команд, определяемого в нескольких строках. Не все командные интерпретаторы могут обрабатывать несколько строк команд. Обычно они ориентированы на ввод одной команды в строке ввода, выполнения ее и ожидания ввода следующей команды. Некоторые командные оболочки могут обрабатывать несколько команд, заданных в одной строке через разделитель, например командный интерпретатор cmd системы Windows NT, в котором разделителем служит символ &.
Результат выполнения операции «документ здесь» можно использовать в качестве операнда строковых операций. Можно даже использовать несколько операций «документ здесь» в одном выражении, расположив строки их данных последовательно друг под другом, не забыв, конечно, строки с соответствующими завершающими идентификаторами:
$stack = <<"ONE".<<"TWO";
Первый
операнд
ONE
Второй
операнд
TWO
Значением скалярной переменной $stack будет следующая строка:
"Первый\nоперанд\nВторой \nоперанд"

Следующая страница Содержание главы


Реклама