Анимация
JavaScript
|
Главная Библионтека Как получить список секретных слов Итак, Главный Директор Списков Секретных Слов желает получить отчет обо всех секретных словах, используемых в текущий момент, с указанием их "возраста". Если мы на минутку расстанемся с программой проверки секретного слова, у нас будет время написать для Директора программу формирования необходимого ему отчета. Сперва давайте получим все нащи секретные слова, воспользовавщись для этого частью кода из подпрограммы init words () : while ( defined($filename = glob("*.secret")) ) { open (WORDSLIST, $filename) I I die "cant open wordlist: $!"; if (-M WORDSLIST >= 7.0) { while ($name = <WORDSLIST>) { chomp ($name); $word = <WORDSLIST> ; chomp ($word) ; ### отсюда начинается новый код } close (WORDSLIST) I I die "couldnt close wordlist: $!" К моменту достижения того места программы, где дан комментарий "отсюда начнется новый код", мы знаем три вещи: имя файла (содержится в переменной $filename), чье-то имя (в переменной Sname) и секретное слово этого человека (содержится в $word). Здесь и нужно использовать имеющиеся в Perl инструменты формирования отчетов. Для этого где-то в программе мы должны определить используемый формат (обычно это делается в конце, как и для подпрограмм): format STDOUT = @<«<«<<«<<<<< @<<«<«<< (?<««<«<« $filename, $name, $word Определение формата начинается строкой format stdout=, а завершается точкой. Две строки между первой строкой и точкой - это сам формат. Первая строка формата - это строка определения полей, в которой задается число, длина и тип полей. В этом формате у нас три поля. Строка, следующая за строкой определения полей - это всегда строка значений полей. Строка значений содержит список выражений, которые будут вычисляться при использовании формата; результаты вычисления этих выражений вставляются в поля, определенные в предыдущей строке. Вызывается определенный таким образом формат функцией write, например: #! /usr/bin/perl while ( defined($filename = glob("*.secret")) ) { open (WORDSLIST, Sfilename) II die "cant open wordlist: $!"; if (-M WORDSLIST >= 7.0) { while ($name = <WORDSLIST>) { chomp ($name); $word = <WORDSLIST> ; chomp ($word); write; # вызвать format STDOUT в STDOUT close (WORDSLIST) die "couldnt close wordlist: $!"; format STDOUT = (a«««<<<<«<<< @<«<<«« @<««««« $filename, $name, $word Когда вызывается формат, Perl вычисляет выражения, имеющиеся в строке значений, и генерирует строку, которую передает в дескриптор файла stdout. Поскольку write вызывается один раз при каждом проходе цикла, мы получим ряд строк (под одной строке для каждого секретного слова); итоговый текст будет разбит на столбцы. Гм-м. Мы забыли дать столбцам названия. Впрочем, это достаточно легко сделать. Нужно просто ввести формат начала страницы: format STD0UT TOP = Page 0« Filename Name Word Этот формат называется stdout top; oh будет использоваться при первом вызове формата stdout, а затем через каждые 60 строк, выведенных в stdout. Заголовки столбцов позиционируются точно по столбцам формата stdout, поэтому все выглядит аккуратно. В первой строке заголовка стоит неизменяемый текст (Page) и трехзначный определитель поля. Следующая строка - строка значений полей, в данном случае она содержит выражение. Это выражение является переменной $%*, в которой содержится число выведенных страниц. Третья строка формата пуста. А поскольку она не содержит никаких полей, то следующая за ней строка тоже пустая; она копируется прямо на вывод, вследствие чего между идущими ниже номером страницы и заголовками столбцов появляется пустая строка. Последние две строки формата также не содержат никаких полей, поэтому они копируются на вывод в том виде, в каком записаны. Таким образом, этот формат обеспечивает создание четырех строк, одна из которых меняется от страницы к странице. Благодаря модулю English можно использовать для этих предопределенных скалярных переменных более мнемонические псевдонимы легко запоминающиеся названия. Чтобы это определение заработало, попробуйте присоединить его к предыдущей программе. Perl отыщет формат начала страницы автоматически. В Perl имеются также поля, которые центрируются и выравниваются по правому краю области вывода. Этот язык, кроме того, поддерживает одновременное выравнивание и по правому, и по левому краям. Подробно об этом мы поговорим, когда дойдем до форматов, в главе 11. Как сделать старые списки слов более заметными Просматривая файлы *.secret в текущем каталоге, мы, возможно, обнаружим слишком старые файлы. До сих пор мы просто пропускали их. Давайте сделаем очередной щаг и переименуем такие файлы в *.secret .old, чтобы в перечне содержимого каталога сразу было видно - по имени - какие файлы необходимо обновить. Вот как выглядит подпрограмма init words () , модифицированная для выполнения такой операции: sub init words { while { defined($filename = glob("*.secret")) ) ( open (WORDSLIST, $filename) I die "cant open wordlist: $!"; if {-M WORDSLIST >= 7.0) ( while ($name = <W0RDSLIST>) ( chomp {$name); $word = <W0RDSLIST>; chomp ($word); $words ($name) = $word; ) else ( # переименовать файл, чтобы он стал более заметным rename {$filename, "$filename.old") I I die "cant rename $filename to $filename.old: $!"; close (WORDSLIST) M die "couldnt close wordlist: $!"; Обратите внимание на новую часть оператора else в блоке проверки "возраста" файлов. Если файл не обновлялся семь дней и более, функция rename переименовывает его. Эта функция принимает два параметра и переименовывает файл, заданный первым параметром, присваивая ему имя, указанное во втором параметре. В Perl имеется полный набор операций, необходимых для манипулирования файлами; все, что можно сделать с файлом в С-программе, можно сделать с ним и в Perl. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [ 15 ] 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |