Пятница, 24.11.2017, 10:23
Приветствую Вас Гость | RSS
Главная | Лекции | Регистрация | Вход
Меню сайта
Форма входа
Логин:
Пароль:
Категории раздела
Лекция [24]
Мини-чат
100
Поиск
Наш опрос
Оцените мой сайт
Всего ответов: 2
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Программирование Perl
    Главная » Статьи » Лекция » Лекция

    Лекция 10.2: Отчеты

    Переключение потоков и форматов

    Без указания файлового манипулятора вывод отчета функцией write() и обычный вывод данных функцией print()происходит в выходной поток по умолчанию (STDOUT). С помощью функции select() можно назначить другой выходной потокпо умолчанию. При вызове ей передается файловый манипулятор, и она переключается на новый поток, который становится текущим выходным потоком по умолчанию. Функция select() возвращает имя ранее выбранного манипулятора, и это значениеиспользуется для восстановления предыдущего выходного потока. Это происходит таким образом:

     
    $old_handle = # сохранить файловый манипулятор
     select $new_handle; # переключиться на новый поток
    write; # вывести в новый поток
    select $old_handle; # восстановить предыдущий поток
     

    При формировании сложного отчета может потребоваться возможность переключаться на разные форматы отчета. Установить для какого-либо потока определенный формат отчета можно путем присваивания имени формата переменной $~ ($FORMAT_NAME). Подобным же образом для конкретного потока устанавливается нужный формат заголовка страницы отчета:переменной $^ ($FORMAT_TOP_NAME) присваивается имя формата для шапки страницы. Это делается так:

     
    $old_handle = select $out; # выбрать поток для отчета
    $^ = 'REPORT_TOP'; # назначить формат для шапки отчета
    $~ = 'REPORT'; # назначить формат для отчета
    write $out; # вывести в $out по формату REPORT
    select $old_handle; # вернуться к предыдущему потоку
     

    Назначать для определенного потока формат отчета и заголовок страницы гораздо удобнее с помощью функций format_name()и format_top_name() из стандартного библиотечного модуля FileHandle. Это выглядит так:

     
    use FileHandle; # подключить модуль работы с файлами
    
    # назначить для потока $report формат отчета REPORT
    format_name $report REPORT; 
    # назначить для потока $report формат заголовка PAGE
    format_top_name $report PAGE;
    # используя назначенные форматы,
    write $report; # вывести строку отчета в $report
     

    Обратите внимание, что при обращении к функциям format_name() и format_top_name() после файлового манипулятора не ставится запятая, так же как при вызове функции print().

     

    Обычные и специальные поля

    Пока что в примерах использовались только обычные поля (regular fields), которые описываются поледержателями, начинающимися с символа @. Поледержатели, описание которых начинается с символа ^, представляют так называемые специальные поля (special fields), обладающие возможностью дополнительной обработки данных. Так, специальные числовые поля (например, ^###), содержащие неопределенное значение (undef), заполняются пробелами. Обычные числовые поля (например, @###) в этом случае выводят нули. Это демонстрирует следующий пример:

     
    format STDOUT =
    обычное:'@##.##' специальное:'^####'
    undef, undef
    .
    write STDOUT; # вывод данных по формату в STDOUT
    # выведет: обычное:' 0.00' специальное:' '
     

    Специальные текстовые поля (например, ^<<<) используются для вывода в отчет данных, располагающихся на нескольких строках.

    Многострочные значения

    Есть несколько способов описать в формате данные, занимающие в отчете несколько строк. Если нужно поместить на страницеотчета многострочное текстовое значение, то можно воспользоваться поледержателем @*, который просто выведет значениеполностью, сохраняя имеющиеся в нем все символы перевода строки, кроме последнего. Например, так делается в этой программе:

     
    format STDOUT = 
    Гамлет:
    @* 
    $multi_line_text
    (У. Шекспир)
    .
    $multi_line_text = "Быть\nИли не быть?\nВот в чем вопрос."; 
    write STDOUT;
     

    В результате ее выполнения будет выведено известное высказывание с сохранением его разбивки на несколько строк:

     
    Гамлет:
    Быть
    Или не быть?
    Вот в чем вопрос.
     (У. Шекспир)
     

    Поледержатель ^* описывает в формате текстовое полезначение которого должно выводиться на несколько строк определенной ширины. В строке аргументов такому полю должно соответствовать имя переменной: скаляра, элемента массива или хэша. Когда значение этой переменной помещается в поле отчета, из переменной извлекается часть текстового значения до первого разделителя строк. Если переменная употребляется в формате несколько раз, то ее значение уменьшается на число извлеченных символов при каждом обращении к ней. Вот как это выглядит на примере:

     
    # выводимое многострочное значение
    $text = "Что значит имя?\nРоза пахнет розой\n"
     . "Хоть розой назови ее, хоть нет.";
    write STDOUT;
    # описание формата отчета
    format STDOUT =
    ^* 
    $text
    ^* 
    $text
    ^* ~
    $text
    ^* ~
    $text
     У.Шекспир, "Ромео и Джульетта"
    .
     

    Обратите внимание, что в формате для вывода значения переменной $text предусмотрены четыре строки. Причем первые две строки отчета (с шаблоном ^* ) будут выводиться в любом случае: даже если $text содержит только одну строку текста, вторая строка будет заполнена пробелами. Чтобы не выводить пробельных строк, в описании третьей и четвертой строк указаншаблон подавления пустых строк (одна тильда, ~), который может располагаться в любом месте строки шаблона. После выполнения приведенной программы текст будет выведен в таком виде:

     
    Что значит имя?
    Роза пахнет розой
    Хоть розой назови ее, хоть нет.
     У.Шекспир, "Ромео и Джульетта"
     

    Если заранее неизвестно минимальное количество выводимых строк, можно применить шаблон повторения многострочного поля (две тильды подряд в любом месте строки, ~~ ). В этом случае строка шаблона будет применяться многократно, пока не будет исчерпано многострочное значение, при этом пустые строки выводиться не будут. Тильды в шаблоне подавления пустых строк и в шаблоне повторения строк при выводе отчета заменяются на пробелы. Таким образом, формат в последнем примере можно заменить на следующий:

     
    format STDOUT =
    ^* ~~
    $text
     У.Шекспир, "Ромео и Джульетта" 
    .
     

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

     

    Для описания в формате текстового значения, которое должно выводиться на несколько строк, применяется поледержатель следующего вида: ^<<<<<. Это специальное поле иногда называется "заполняемым полем". Оно предназначается дляформатирования текстового значения, которое при выводе в отчет делится на строки, не превышающие ширину шаблона. Делениена строки производится по границам слов. Источником выводимого текста обязательно должна быть переменная со скалярным значением, из которой при каждом ее употреблении в формате извлекается столько слов, сколько поместится в соответствующемполе отчета. Заполнение шаблона текстом и вывод отчета в несколько строк иллюстрирует следующий пример:

     
    my $shakespeare = 'Две равно уважаемых семьи '
     . 'В Вероне, где встречают нас событья, '
     . 'Ведут междоусобные бои '
     . 'И не хотят унять кровопролитья.';
    my $text = $shakespeare;
    write STDOUT;
    # описание формата вывода
    format STDOUT = 
    ~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
     $text 
     У.Шекспир, "Ромео и Джульетта"
    .
     

    В этом примере для организации неявного цикла вывода также применяется шаблон повторения строк, поскольку неизвестно, сколько строк будет заполнено выводимым текстом. При выполнении примера будет выведен текст в таком виде:

     
    Две равно уважаемых семьи В Вероне,
     где встречают нас событья, Ведут
     междоусобные бои И не хотят унять
     кровопролитья.
     У.Шекспир, "Ромео и Джульетта"
     

    Подобным образом в отчет выводятся блоки текстовой информации: примечания, описания, адрес и т. п.

    Специальные переменные форматов

    Кроме переменных, в которых хранятся имена формата ($~) и заголовка страницы формата ($^), есть еще несколько специальныхпеременных для хранения информации о форматах. Номер текущей страницы выводимого отчета содержится в переменной $% ($FORMAT_PAGE_NUMBER), и ее часто включают в формат отчета. В переменной $= ($FORMAT_LINES_PER_PAGE) хранится число строк на странице: по умолчанию - 60, но его можно изменить на нужное значение перед выводом отчета. В переменной$- ($FORMAT_LINES_LEFT) содержится число оставшихся на странице строк. Переменная $^L ($FORMAT_FORMFEED) хранит символ перевода страницы (formfeed character), который используется в отчетах для прогона принтера до новой страницы.

     

    Специальная переменная $: ($FORMAT_LINE_BREAK_SEPARATOR) содержит набор символов разрыва строки, после которых строка может быть разделена при заполнении в формате специальных полей продолжения. Специальная переменная $^A ($ACCUMULATOR) является аккумулятором выводимых данных для функций formline() и write(), в котором накапливаются данные отчета перед их отправкой в выходной поток. При считывании данных для отчета из файла может пригодитьсяпеременная $. ($INPUT_LINE_NUMBER), в которой хранится номер прочитанной из входного файла строки, что можно использовать для нумерации строк в отчете.

     

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

     
    perldoc perlform
     

    В завершение лекции приведем пример законченной программы (с образцом исходных данных), выводящей отчет о книгах поязыку Perl.

     
    open my $report, '>', '/report.txt' or die;
    $old_handle = select $out; # выбрать поток для отчета
    select $report;
    $^ = 'HEAD';
    $~ = 'REPORT';
    # описание форматов для отчета
    while(<DATA>) { # чтение одной записи данных
     ($authors, $title, $year, $nick) = split ':';
     write $report; # вывод одной строки отчета
    }
    close $report or die;
    # формат для заголовка страницы
    format HEAD =
     Классические книги по языку Perl 
     издательства O'Reilly
     Лист @#
     $%
    ---------------+--------------------+----+------------
     Авторы | Заглавие |Год | Прозвище
    ---------------+--------------------+----+------------
    .
    format REPORT =
    ^<<<<<<<<<<<<<<|^<<<<<<<<<<<<<<<<<<<|@###|@>>>>>>>>>>>
    $authors, $title, $year, $nick
    ^<<<<<<<<<<<<<<|^<<<<<<<<<<<<<<<<<<<| | ~~ 
    $authors, $title 
    ---------------+--------------------+----+------------
    .
    __DATA__
    Cozens S.:Advanced Perl Programming,2nd ed.:2005:Panther Book
    Friedl J.E.F.:Mastering Regular Expressions:1997:Owls Book
    ...
     

    Результатом работы этой программы будет такой отчет, размещенный в файле report.txt:

     
    Классические книги по языку Perl
     издательства O'Reilly
     Лист 1
    ---------------+--------------------+----+------------
     Авторы | Заглавие |Год | Прозвище
    ---------------+--------------------+----+------------
    Cozens S. |Advanced Perl |2005|Panther Book
     |Programming,2nd ed. | |
    ---------------+--------------------+----+------------
    Friedl J.E.F. |Mastering Regular |1997| Owls Book
     |Expressions | |
    ---------------+--------------------+----+------------
    Schwartz R.L., |Learning Perl, 4th |2005| Llama Book
    Phoenix T., |ed. | |
    brian d foy | | |
    ---------------+--------------------+----+------------
     

    Конечно, изученные в этой лекции средства отчетов не могут сравниться с современными специализированными построителями отчетов, но во многих случаях бывает достаточно форматирования выходных данных в виде простых отчетов, которое в Perlделается достаточно легко, просто и наглядно. Эта лекция была "лирическим отступлением" перед тем как начать углубленное изучение техники программирования на языке Perl.

    Категория: Лекция | Добавил: mazay (13.05.2014)
    Просмотров: 247 | Рейтинг: 0.0/0
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Создать бесплатный сайт с uCozCopyright MyCorp © 2017