Шаг 51.
Использование нескольких форматов

    На этом шаге мы рассмотрим способы переключения между форматами.

    На прошлом шаге мы рассмотрели вопросы, связанные с созданием верхних колонтитулов. Напомним, что для этого следует только объявить формат с суффиксом _ТОР. Для создания полноценного документа не мешало бы еще иметь возможность создавать нижние колонтитулы страницы и печатать, например, в конце заказа общую стоимость. К сожалению, такой возможности Perl не предоставляет, но он позволяет переключать вывод с одного формата на другой и в специальной переменной хранит строку, которую печатает перед переходом на новую страницу. А это и позволит нам создать и напечатать и нижний колонтитул, и общую стоимость заказа.

    Но прежде мы еще немного поговорим о специальных переменных Perl, которые используются для управления форматом. В переменной $~ хранится имя формата, который используется при выводе функцией write() без параметра:

   write; # Эквивалентно оператору write STDOUT;

    По умолчанию в ней хранится имя формата STDOUT, но и вывод функцией write() без параметра происходит на стандартное устройство вывода STDOUT. Напомним, что имя формата должно совпадать с именем дескриптора файла в вызове функции write(), а именно такая ситуация по умолчанию и реализуется. Если мы изменим значение переменной $~ на имя другого формата, то вывод в стандартный файл функцией write() без параметра будет осуществляться в соответствии с указанным форматом, который, конечно, должен быть объявлен в программе. Например, следующая функция write() выводит на стандартное устройство вывода в соответствии с форматом NEW:

$~ = NEW; 
write; 
format NEW =
 .    .    .    .
.

    Таким образом, меняя значение переменной $~, можно переключать вывод с одного формата на другой. Этим другим форматом как раз и может быть формат общей стоимости заказа.


    Пример 1. Пусть в файле books содержится информация о заказанных книжным магазином книг. В конце отчета по заказу нам теперь необходимо напечатать общую стоимость книг. Решение показано ниже.
#! 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 попадут не в конец текущей страницы, а будут напечатаны на следующей странице, не создав никакого нижнего колонтитула.


    Пример 2. Использование переменной $^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.

    Со следующего шага мы начнем рассматривать ссылки.




Предыдущий шаг Содержание Следующий шаг