На этом шаге мы рассмотрим способы переключения между форматами.
На прошлом шаге мы рассмотрели вопросы, связанные с созданием верхних колонтитулов. Напомним, что для этого следует только объявить формат с суффиксом _ТОР. Для создания полноценного документа не мешало бы еще иметь возможность создавать нижние колонтитулы страницы и печатать, например, в конце заказа общую стоимость. К сожалению, такой возможности Perl не предоставляет, но он позволяет переключать вывод с одного формата на другой и в специальной переменной хранит строку, которую печатает перед переходом на новую страницу. А это и позволит нам создать и напечатать и нижний колонтитул, и общую стоимость заказа.
Но прежде мы еще немного поговорим о специальных переменных Perl, которые используются для управления форматом. В переменной $~ хранится имя формата, который используется при выводе функцией write() без параметра:
write; # Эквивалентно оператору write STDOUT;
По умолчанию в ней хранится имя формата STDOUT, но и вывод функцией write() без параметра происходит на стандартное устройство вывода STDOUT. Напомним, что имя формата должно совпадать с именем дескриптора файла в вызове функции write(), а именно такая ситуация по умолчанию и реализуется. Если мы изменим значение переменной $~ на имя другого формата, то вывод в стандартный файл функцией write() без параметра будет осуществляться в соответствии с указанным форматом, который, конечно, должен быть объявлен в программе. Например, следующая функция write() выводит на стандартное устройство вывода в соответствии с форматом NEW:
$~ = NEW; write; format NEW = . . . . .
Таким образом, меняя значение переменной $~, можно переключать вывод с одного формата на другой. Этим другим форматом как раз и может быть формат общей стоимости заказа.
#! perl -w open BOOKS, "< books"; # Открытие файла на чтение. $total = 0; while (<BOOKS>) { # Разбиение строки по символу ' : '. ($author, $title, $pub, $year, $price) = split (':'); write; # Форматный вывод строки. $total += $price; # Подсчет общей суммы. } $~ = TOTAL; # Переключение формата. write; # Вывод по формату итоговой строки. format STDOUT = @<<<<<<<<<<<<<<<<<<<<<<<<< | ^>>>>>>>>>>> | @||||||| | @#### | @###.##р. $author, $title, $pub, $year, $price | ^>>>>>>>>>>> | | |~~ $title . format STDOUT_TOP = Книги на складе @>>>>>> "стр. ".$% Автор Название Издатель Год Цена ======================================================================== . format TOTAL = ======================================================================== Итого: @###.##p. $total ======================================================================== .
В этой программе после форматной печати содержимого файла books осуществляется переключение на другой формат, по которому выводится строка с общей суммой заказа, подсчитанной в переменной $total. Полученный с помощью этой программы заказ показан ниже:
Рис.1. Результат работы приложения
В заключение модифицируем программу примера 1, приспособив ее для печати отчета на основании информации о книгах из файла books, в котором в записи о книгах добавлено еще одно поле, содержащее краткую аннотацию книги:
В.Долженков Ю.Колесников:Excel 2000:BHV:1999:90:Аннотация книги
Отчет, формируемый этой программой (пример 2), также печатает нижний колонтитул на каждой странице. Для этого мы воспользуемся специальной переменной $^L, содержимое которой Perl печатает перед переходом на новую страницу во время форматного вывода. При этом следует уменьшить на количество строк, заданных в этой переменной, количество строк на странице, хранящееся в специальной переменной $=, иначе строки из переменной $^L попадут не в конец текущей страницы, а будут напечатаны на следующей странице, не создав никакого нижнего колонтитула.
#! perl -w open BOOKS, "< books" or die $!; # Открытие файла на чтение. open REPORT, "> report" or die $!; select REPORT; $~ = STDOUT; $= = 12; $ltime = localtime; $^L = ("=" x 73)."\n"."Книготорговая база \"СИРИУС\"". (" " x 24)."$ltime\n\f"; $count = 0; while (<BOOKS>) { # Разбиение строки по символу ' : '. ($author, $title, $pub, $year, $price, $annot) = split (':'); $count++; write; # Форматный вывод строки. } close(REPORT); format STDOUT = @| ^<<<<<<<<<<< ^<<<<<<<<<<< @<<<<<<< @### @###.##р. ^<<<<<<<<<<<<<<<<<< $count.".", $author, $title, $pub, $year, $price, $annot ^<<<<<<<<<<< ^<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<< ~~ $author, $title, $annot . format STDOUT_TOP = Книги на складе @>>>>>> "стр. ".$% Автор Название Издатель Год Цена Аннотация ======================================================================== .
Результат работы приложения изображен на рисунке 2:
Рис.2. Результат работы приложения
Вывод отчета осуществляется в файл с именем report. Обратите внимание на задание переменной $^L. В ней используется переменная $ltime, в которой хранится текущая дата, полученная обращением к функции localtime.
Со следующего шага мы начнем рассматривать ссылки.