Часть I. Синтаксис Perl

Глава 1. Основы Perl

Коротко

В этой главе рассказывается об основе основ Perl — создании и запуске сценариев Perl. Навыки, полученные в этой главе, обеспечат читателю, не знакомому с Perl, фундамент, который потребуется для восприятия остальных частей книги. Кроме создания и запуска сценариев мы рассмотрим вывод текста на экран и ввод текста с клавиатуры. Возможно, читатель уже знаком с большей частью материала этой главы, в этом случае она может служить обзорной. Однако часть материала, по-видимому, будет новой. Например, немногие люди навскидку способны перечислить, что именно делает каждый из ключей, задаваемых в командной строке при запуске интерпретатора.

Язык Perl был создан в 1986 году как инструмент для администрирования и конфигурирования системных ресурсов в сети, состоящей из Unix-компьютеров. Постепенно Perl (чья аббревиатура расшифровывается как Практический Язык для Извлечения текстов и Генерации отчетов (Practical Extraction and Reporting Language) или же — нежно и ласково — как Патологически Эклектичный Язык для Распечаток Чепухи (Pathologically Eclectic Rubbish Listing)) эволюциониро вал в межплатформенный язык и оказался в центре внимания процветающего кибернетического сообщества.

(Вы можете спросить: почему «Perl», а не «Pearl», то есть «жемчужина»? Дело в том, что графический язык с именем Pearl к моменту создания Perl уже существовал. Кроме того, обратите внимание, что точная аббревиатура слов Practical Extraction and Reporting Language, при включении первых букв всех слов, будет представлять собой именно Pearl.)

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

Некоторые люди удивляются популярности Perl (языка, ориентированного на текстовый ввод и вывод и запускаемого из командной строки) в мире графических интерфейсов типа Windows. Популярность Perl продолжает расти по ряду причин.

Глава 1. Основы Perl

Многие операционные системы остаются текстово-ориентированными.

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

· На самом деле Perl обладает определенными графическими возможностями за счет взаимодействия с популярным модулем Tk.pm (мы рассмотрим его в главе 13). Данный модуль позволяет использовать стандартные графические интерфейсные элементы (widgets) с помощью вспомогательного средства — библиотеки Tk языка Tcl. Это позволяет создавать из Perl окна с кнопками, меню и другими объектами.

· Однако с точки зрения явного большинства программистов текущая популярность Perl подпитывается программированием Common Gateway Interface (CGI-программированием), применяемого для операций по взаимодействию клиент/сервер в среде Web. Когда речь идет о создании Web-страниц, текстовая ориентированность языка перестает быть недостатком, так как они также являются чисто текстовыми объектами. CGI-программирование на Perl представляет собой очень мощный инструмент, и, соответственно, это одна из основных тем, которые мы будем рассматривать.

А теперь перейдем к запуску нескольких сценариев.

Непосредственные решения

Как скопировать и установить Perl

Perl является свободным программным продуктом. Достаточно скопировать и установить его. Если вы работаете на компьютере с несколькими пользователя ми или в многопользовательской системе, то Perl, возможно, уже установлен. Попробуйте выдать команду

%perl -v

в командной строке.

Подсказка. На протяжении этой книги знак процента (%) в начале строки означает приглашение командной строки для операционной системы Unix и вводить его не надо.

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

Обратите внимание, что для некоторых систем интерпретатор Perl, используемый по умолчанию, относится к более ранней версии — например, к версии 4. Чтобы использовать Perl версии 5, вам потребуется команда типа perl5 (попробуйте ее, если perl -v выдает версию, отличную от 5):

%perl5 -v

Если Perl не установлен, вы можете найти его на www.perl.com или www.cpan.org. (CPAN — Comprehensive Perl Archive Network — самый полный электронный архив материалов, имеющих отношение к языку Perl. По мере чтения этой книги вы узнаете об этом ресурсе больше.) На этих узлах вы можете найти и загрузить все, что вам нужно.

Я намеренно не собираюсь описывать процессы инсталляции, которые нужно выполнить для разных операционных систем, чтобы установить Perl. Во-первых, эти процедуры тщательно детализированы и описаны на указанных узлах (например, руководство по инсталляции Perl для Unix находится на www.perl.com/CPAN-local/doc/relinfo/INSTALL.html). Во-вторых, они подвержены спонтанным изменениям, которые не могут быть отражены в книге. (Многие книги устарели за счет описания детальных инструкций по инсталляции — например, книги по языку Java, — поскольку эти инструкции изменялись чуть ли не моментально с появлением новой версии.)

Самая последняя версия Perl может быть получена, если выбрать ссылку «Get the latest version of Perl» на узле www.perl.com. Эта ссылка приведет вас к страничке, на которой перечислены версии Perl для наиболее популярных операционных систем (например, ActiveState Perl для Win32). Убедитесь, что вы получили версию 5.005 или более позднюю, поскольку предыдущие версии Perl для Win32 не вполне совместимы с Perl для Unix и его модулями.

Глава 1. Основы Perl

Как написать сценарий для Perl

Сценарии Perl представляют собой простые текстовые файлы, в которых находятся описания и команды. (Как вы увидите позднее, все, что вам надо сделать, — это описать форматы и подпрограммы.) Чтобы создать сценарий Perl, надо иметь текстовый редактор или текстовый процессор, который может сохранять редактируемые файлы в формате простого текста.

Сохранение файла в формате простого текста — элементарное действие, которое может оказаться за пределами возможностей хитроумного текстового процессора. Например, легко столкнуться с трудностями при работе с программой Microsoft Word, хотя и там можно сохранить результат редактирования как простой текст, если вы используете окно диалога File|Save As. Общее правило гласит: если при выводе файла на экран из командной строки (например, с помощью команды type) не появляется странных небуквенных символов, — это формат простого текста. Истинная проверка, естественно, будет в том, сможет ли Perl прочитать и скомпилировать ваш сценарий.

В этой книге для стандартных сценариев Perl используется расширение .pl. Например, сценарий, который будет приведен чуть позже, получит имя hello.pl. Сценарии Perl не требуют такого расширения (например, другое типичное расширение  — это .p) и, более того, вообще могут без них обходиться. Тем не менее для Perl-сценариев традиционно используют расширение .pl. В частности, популярный интерпретатор ActiveState Perl для Win32 ассоциирует расширение .pl с интерпретато ром Perl, так что вы можете запускать сценарии автоматически, дважды щелкнув по имени файла. Естественно, никто не заставляет для сценариев использовать расширение .pl, равно как и вообще присоединять расширение к имени файла.

Убедитесь, что сценарий сможет найти Perl

Как вы узнаете из раздела «Выполнение сценариев Perl», существуют два основных способа запуска Perl-сценариев. Во-первых, можно запустить интерпретатор Perl в явном виде из командной строки

%perl hello.pl

Можно также настроить систему так, чтобы сценарий сам запустил интерпрета тор Perl. В этом случае сценарий выполняется командой типа:

%hello.pl

или в случае, когда текущий каталог не включается в путь поиска по соображениям безопасности, командой типа1:

%./hello.pl

Система настроек в различных операционных системах устроена по-разному.

1 Например, в Unix по указанным соображениям текущий каталог, как правило, не включается в список путей поиска. Поэтому если вы просто введете имя сценария в командной строке в виде «hello.pl», то ваш сценарий может быть выполнен лишь в том случае, если он находится в каталогах, куда обычному пользователю что-либо записывать запрещено (Unix попросту не сможет найти команду«hello.pl», если она не находится в системном каталоге). В силу этого данный авторский пример был нами слегка подкорректирован. — Примеч. ред.

 

Убедитесь, что сценарий сможет найти Perl

Unix

Операционной системе Unix можно объяснить, что для запуска сценария надо вызвать интерпретатор Perl, если в первой строке файла находится следующий текст (учтите, что такой строки не требуется, если вы запускаете сценарий на выполнение обычным способом):

#!/usr/local/bin/perl # Use Perl

Строчка с такой специфической синтаксической конструкцией, как #!, обязатель но должна стоять в файле первой. Эта строка содержит ссылку на каталог, в котором на большинстве компьютеров с операционной системой Unix располагается интерпретатор Perl. Perl также может располагаться в другом месте — например, /usr /bin/perl (обратите внимание, что на многих машинах оба пути ссылаются на один и тот же файл). Чтобы выяснить, где находится Perl, используйте команду which perl.

Чтобы указать, что вам требуется Perl 5, для большинства систем можно использовать строку

#!/usr/local/bin/perl5 # Use Perl 5

При запуске интерпретатора, чтобы гарантировать вывод предупреждающих сообщений по мере обработки интерпретатором вашего кода, рекомендуется использовать ключ -w. (На самом деле интерпретатор Perl компилирует код целиком при его загрузке. Поэтому предупреждающие сообщения появятся сразу же, если только вы не загружаете откомпилированный код позже. Это можно сделать с помощью команды Perl require, которая загружает код во время выполнения сценария. Мы увидим, как это делается, в главе 15.)

#!/usr/local/bin/perl5 -w # Use Perl 5 with warnings

Поскольку во многих системах Unix строка с шаблоном #! обрезается после 32 знаков, при попытке ввести для Perl длинный путь вы встретитесь с проблемой:

#!/usr/local/bin/users/standard/build36/perl5

В подобных случаях, а также если ваша система не поддерживает синтаксичес кие конструкции вида !#, можно использовать вызов командного интерпретато ра sh с тем, чтобы запустить Perl «обычным путем»:

#!/usr/sh

eval `/usr/local/bin/perl5 -wS $0 ${1+"$@"}' if 0;

Здесь используется команда eval командного интерпретатора с тем, чтобы выполнить запуск Perl. Ключ -w обеспечивает вывод предупреждающих сообщений. Параметр $0 должен включать в себя полный путь, однако иногда этот механизм не работает. Поэтому ключ -S заставляет Perl при необходимости самостоятель но искать сценарий. Странная конструкция ${1+"$@"} обрабатывает имена с внутренними пробелами. Обратите также внимание, что наш пример запускает интерпретатор Perl, но не возвращает значения (кода завершения), так как оператор if 0 никогда не является истинным.

Глава 1. Основы Perl

Вы можете использовать строку типа

#!/usr/local/bin/perl5 -w

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

Подсказка. Перед тем как запускать сценарий Perl под Unix в качестве команды (то есть просто указывая его имя в командной строке, например «./script.pl», а не «perl script.pl»), вам нужно присвоить ему статус исполняемого файла. Для этого просмотрите раздел «Выполнение сценариев Perl», который можно найти в этой же главе немного далее.

MS-DOS

В операционной системе MS-DOS вы можете гарантировать, что сценарий найдет интерпретатор Perl, если преобразуете его в .bat-файл с помощью утилиты pl2bat.bat. (Она входит в комплект пакета ActiveState Perl.)

Например, если у вас есть сценарий hello.pl:

print "Hello!\n";

print "Press <Enter> to continue...";

<STDIN>;

то с помощью команды

C:\>pl2bat hello.pl

вы преобразуете его в файл hello.bat. Результирующий файл будет выглядеть следующим образом:

@rem = `--*-Perl-*--

@echo off

if "%OS%" == "Windows_NT" goto WinNT

perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9

goto endofperl

:WinNT

perl -x -S "%0" %*

if NOT "%COMSPEC%"=="%SystemRoot%\system32\cmd.exe" goto endofperl

@rem `;

#!perl

#line 14

print "Hello!\n";

print "Press <Enter> to continue...";

<STDIN>;

__END__

:endofperl

 

Как написать программу Perl: команды и описания

Windows 95/98 и Windows NT

Пакет ActiveState Perl для Windows 95/98 и Windows NT модифицирует реестр Windows так, что файлы с расширением .pl ассоциируются с интерпретатором Perl. Двойной щелчок мышью на файле сценария запускает его на выполнение. Однако когда это происходит, открывается окошко MS-DOS, в нем запускает ся интерпретатор Perl, а затем окно MS-DOS немедленно закрывается (до того, как вам удается прочитать выведенный текст). Для того чтобы избежать этого эффекта, посмотрите раздел «Как избежать немедленного закрытия окна MSDOS в Windows 95/98/NT», который можно найти в этой же главе немного ниже.

Macintosh

На компьютерах Macintosh сценарии Perl выполняются автоматически — для вызова Perl дважды щелкните на сценарии мышью.

Как написать программу Perl: команды и описания

Программа на Perl состоит из команд и описаний. Описания указывают Perl, как вы собираетесь использовать определенные программные конструкции до того, как это произойдет на самом деле. Они нужны только для форматов и подпрограмм, хотя можно также описывать и другие элементы типа переменных. Более подробно об описаниях речь пойдет в этой книге дальше.

Команды встречаются в двух формах: простой и составной. Простая команда — это выражение, выполняющее некоторое конкретное действие. В программе простые команды заканчиваются точкой с запятой (;), как происходит в следующем примере, где функция print используется для вывода на экран строки Hello!, завершаемой символом перевода строки \n (см. раздел «Основные команды форматирования» далее в этой главе):

print "Hello!\n";

Составные команды состоят из выражений и блоков. Блоки в языке Perl ограничиваются фигурными скобками ({) и (}) и могут содержать несколько простых команд. Они также имеют свои области видимости (область видимости элементов типа переменных — это сегмент программы, в котором можно использовать переменную; более подробно этот вопрос рассматривается далее). После закрывающей фигурной скобки не надо ставить точку с запятой.

Далее следует пример блока, с помощью которого создается составной оператор цикла for (это фундаментальный оператор цикла в Perl, мы будем подробно его исследовать в главе 5):

for ($loop_index = 1; $loop_index <= 5; $loop_index++) {

print "Hello!";

print "there!\n";

}

Выполнение сценариев Perl

Предположим, что имеется файл hello.pl со следующим сценарием на Perl:

#!/usr/local/bin/perl5 -w # Use Perl5 with warnings

print "hello\n";

как его выполнить? Это основная операция при работе с Perl. Однако, поскольку имеется несколько вариаций на основную тему, мы сделаем краткий обзор имеющихся возможностей.

Как ваш сценарий может найти Perl сам

Если ваш сценарий может запустить интерпретатор Perl самостоятельно (см. раздел «Убедитесь, что сценарий сможет найти Perl» ранее в этой главе), вам легко его выполнить. Для Unix это значит, что первая строка файла содержит текст типа #!/usr/local/perl5 -w. Кроме того, сценарий надо сделать исполняемым файлом. Это осуществляется с помощью команды

chmod +x hello.pl

Также следует убедиться, что сценарий расположен в одном из путей поиска.

Например, для этого следует проверить ваш файл .login и провести поиск команд set path, если в качестве командной оболочки используется csh или одна из его производных. Если же для этой цели используется sh или аналогичный интерпретатор, проверьте команду PATH. В случае применения другого типа оболочки используйте ее специальные команды (в крайнем случае, сверьтесь со справочником). После этого запустите сценарий на выполнение, введя в командной строке команду типа:

%hello.pl

В операционных системах Windows или Macintosh, чтобы запустить сценарий, нужно дважды щелкнуть на его имени. Убедитесь, что в случае Windows файл имеет расширение .pl, поскольку пакет ActiveState Perl использует именно это расширение для ассоциирования файлов скриптов с интерпретатором Perl.

Если вы работаете в операционной системе MS-DOS, то, преобразовав с помощью утилиты pl2bat.bat Perl-сценарий к форме командного файла (см. раздел «Убедитесь, что сценарий сможет найти Perl» ранее в этой главе), просто запустите этот файл из командной строки

C:\>hello.bat

Как использовать командную строку

Чтобы запустить сценарий на выполнение с помощью вызванного в явном виде интерпретатора, убедитесь, что программа с именем perl находится в одном из путей поиска. Затем введите в командной строке команду perl. Она может иметь следующий синтаксис:

perl [-sTuU] [-hv] [-V[:configvar]] [-cw]

[-d[:debugger]] [-D[number/list]] [-pna]

 

Выполнение сценариев Perl

[-Fpattern] [-l[octal]] [-O[octal]] [-Idir]

[-m[-]module] [-M[-]'module...'] [-P] [-S]

[-x[dir]] [-i[extension]] [-e `command']

[--] [programfile] [arguments]

(Ключи в квадратных скобках являются необязательными. Об их назначении речь пойдет далее в разделе «Ключи командной строки» этой главы.)

При запуске интерпретатора Perl сценарий ищется следующим образом:

· Если задан ключ -e, то команды для Perl указываются в командной строке следом за этим ключом.

· Сценарий берется из файла, который стоит первым в списке параметров командной строки (в нашем примере это [programfile]).

· Если в качестве имени файла задан дефис (_), то сценарий считывается построчно из стандартного потока ввода.

Рассмотрим каждый из этих способов.

Использование ключа -e позволяет задавать команды Perl и запускать интерпретатор из одной и той же командной строки. (В некоторых системах вы можете использовать несколько ключей -e, чтобы передать несколько блоков команд.) Например:

%perl -e `print "Hello!\n";'

Hello!

Однако с кавычками надо быть осторожнее, так как в разных операционных системах они работают по-разному. Вот, например, как выглядит та же самая команда в MS-DOS:

c:\>perl -e "print \"Hello!\n\";"

(Обратите внимание на escape-последовательности \", заменяющие двойные кавычки в теле команды Perl. Более подробно эти конструкции рассматриваются в разделе «Основы форматирования текста» далее в этой главе.)

Конечно, можно поместить сценарий в текстовый файл и передать интерпрета тору имя файла. Например, если содержимым файла hello.pl является

print "Hello!\n";

(магическая строчка с шаблоном !# опущена, так как интерпретатор запускается в явном виде), то этот сценарий запускается как

%perl hello.pl

Hello!

Можно также вводить команды Perl построчно с клавиатуры, если вместо имени файла указан дефис:

%perl -

(Здесь даже дефис можно опустить, поскольку такой метод предполагается по умолчанию.) Тогда интерпретатор будет ждать, пока вы не введете сценарий:

%perl -

print "Hello!\n";

Интересный вопрос: а как интерпретатор определит, что сценарий введен и пора приступить к его выполнению? Это произойдет, когда на экране появится инструкция __END__, означающая конец текста:

%perl -

print "Hello!\n";

__END__

Hello!

Такой метод означает выполнение всего сценария целиком. При тестировании эффективнее вводить команды по очереди и выполнять их в интерактивном режиме. Для этого необходимо создать мини-интерпретатор Perl (на Perl J), чем мы и займемся в следующем разделе.

Интерактивное выполнение сценариев Perl

Во время тестирования может потребоваться последовательно выполнять команды Perl по мере их ввода и наблюдать на экране результат их действия. Для этого необходимо написать Perl-оболочку. Вот небольшой работающий пример:

#!/usr/local/bin/perl5 -w # Use Perl 5 with warnings

use strict; # Require variable declarations, etc.

my $count=0; # $count used to match {}, (), etc.

my $statement=""; # statement holds multi-line commands

local $SIG{__WARN__} = sub{}; # supress error reporting

while (<>) { # Accept input from the keyboard

chomp; # Clean-up input

while (/{|\(|\[/g) {$count++}; # Watch for {, (, etc.

while (/}|\)|\]/g) {$count--}; # Watch for }, ), etc.

$statement .= $_; # Append input to current statement

if (!$count) { # Evaluate only if {, ( matches }, )

eval $statement; # Evaluate Perl statement

if ($@) {print "Syntax error.\n"}; # If error ...

$statement = ""; # Clear the current statement

$count = 0; # Clear the counter

}

}

Этот сценарий представляет собой простейшую Perl-оболочку, которая может обрабатывать составные команды, в том числе и те, что охватывают несколько строк ввода. Он работает за счет вызова функции Perl eval, которая вычисляет выражение, переданное ей в качестве аргумента. Эта программа также запоминает вводимый текст (разбитый на несколько строк ввода) до тех пор, пока число открывающих скобок не будет соответствовать числу закрывающих скобок, и лишь затем обращается к функции eval. (До некоторой степени это гарантирует, что разбитое на несколько строк выражение действительно введено полностью. Однако внимательный читатель, безусловно, заметит, что такая оболочка не делает различия между различными типами скобок и не проверяет правильную их вложенность.) Например, можно запустить этот сценарий и ввести команду, ко

 

Ключи командной строки

торая заносит текст в переменную Perl (относительно переменных — см. следующую главу):

$text = "Hello!\n";

а затем распечатать ее:

$text = "Hello!\n";

print $text;

Результат появится на экране немедленно:

$text = "Hello!\n";

print $text;

Hello!

Точно так же можно проверить, как выполняются многострочные команды (так как каждая команда выполняется, когда она полностью введена, результат работы команды print появляется на экране мгновенно):

$variable1 = 1;

$variable2 = 2;

print $variable1 + $variable2;

4

Аналогичным образом обрабатываются составные команды, занимающие более одной строчки:

for ($loop_index = 1; $loop_index <= 5; $loop_index++) {

print "Hello!\n";

}

Hello!

Hello!

Hello!

Hello!

Hello!

Чтобы выйти из оболочки, введите команду exit.

Стандартные оболочки Perl (подобные данной) бывают полезны при тестирова нии коротких сценариев, ибо не требуют создания отдельных файлов и их загрузки в интерпретатор. (Обратите внимание, что данная оболочка — лишь пример, а никоим образом не законченная оболочка Perl. В частности, если тестовый сценарий содержит команду eval, вы встретитесь с серьезными проблемами, так как оболочка сама использует команду eval для пошагового выполнения команд Perl.)

Ключи командной строки

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

perl [-sTuU] [-hv] [-V[:configvar]] [-cw]

[-d[:debugger]] [-D[number/list]] [-pna]

[-Fpattern] [-l[octal]] [-0[octal]] [-Idir]

[-m[-]module] [-M[-]'module...'] [-P] [-S]

[-x[dir]] [-i[extension]] [-e `command']

[--] [programfile] [arguments] ...

(как обычно, квадратные скобки указывают на необязательность соответствую щей конструкции).

Итак, что же делают все эти ключи? Они перечислены здесь в алфавитном порядке (многие, однако, предоставляют возможности, которые мы обсудим позднее):

· -0[цифры] — задает разделитель входных записей как символ, заданный восьмеричным представлением (этот разделитель также содержится в специальной переменной Perl $/). По умолчанию в качестве разделителя выступает символ \n. Если ключ -0 задан без последующих цифр, то используется символ \0.

· -a — включает режим авторазбивки (действует только при наличии ключей p и -n). При этом режиме входные строки разбиваются на фрагменты по границе слова и помещаются в специальный массив @F (то есть вместо скалярной переменной $_ надо будет использовать его).

· -c — заставляет Perl проверять синтаксис входного сценария и завершать работу без его выполнения. Впрочем, блоки BEGIN и END (конструкторы и деструкторы модулей) будут выполнены и в этом случае.

· -d — запускает сценарий под управлением встроенного отладчика Perl.

· -d:имя — запускает сценарий под управлением отладчика или трассировщи ка, инсталлированного как Devel::имя (то есть отладчик существует как подмодуль модуля Devel, имеющий указанное имя — см. главу 15).

· -D[число/список] — устанавливает флаги режима отладки (аргумент — двоичная маска или список флагов). Более подробно флаги отладки рассматрива ются в главе 17.

· -e команда или -e 'команды... ' — используется для непосредственного выполнения команд Perl, задаваемых прямо в командной строке. В некоторых системах можно использовать одновременно несколько ключей -e, разбивая список команд Perl на блоки.

· -Fшаблон или -F/шаблон/ — задает шаблон для разбивки входных строк на блоки, когда заданы ключи -n или -p, а также ключ -a. Символы наклонной черты, окружающие шаблон разбивки, необязательны.

· -h — выводит краткий список ключей с пояснениями.

· -i или -iрасширение — разрешает редактировать «на месте» файлы, открытые из стандартного потока ввода (конструкция <> — см. далее раздел «Чтение потока ввода»). Режим редактирования «на месте» означает, что изменения вносятся непосредственно в открытый файл, когда вы выводите данные в поток ввода STDIN. Если после ключа указано расширение, то Perl обеспечивает резервную копию редактируемого файла, создавая файл c заданным расширением и тем же самым именем. Если же расширение не указано, то временная копия файла, созданная интерпретатором, удаляется после завершения работы.

 

Ключи командной строки

· -Iкаталог — задает каталог, в котором Perl ищет модули. В командной строке может быть задано несколько параметров -I.

· -l — управляет обработкой символов начала новой строки. Если этот ключ задан вместе с -p или -n, Perl при вводе автоматически удаляет символ начала новой строки (заданный в специальной переменной $/). Одновременно при выводе оператором print тот же символ добавляется в конец строки.

· -l[цифры] — в дополнение к функциям предыдущего ключа позволяет задать в явном виде символ, выступающий в качестве начала новой строки (и занести его в переменную $/) — для этого достаточно задать восьмеричное число, определяющее код символа. По умолчанию в качестве разделителя строк используется символ \n.

· -m[-]модуль , -M[-]модуль или -M[-]'модули...' — без знака дефиса этот ключ подключает указанные модули. Если ключ используется со знаком дефиса, указанные модули исключаются из сценария. Действие ключа без дефиса аналогично прагме Perl «use модуль» в начале сценария. Соответственно, действие ключа с дефисом аналогично прагме «no модуль». При старте интерпретатора в командной строке можно указывать несколько параметров -m или -M.

· -n — Perl считает, что сценарий заключен в цикл while (<.>)(см. далее раздел «Чтение потока ввода» относительно конструкции <>). Например, следующая команда выводит на экран содержимое файла file.txt:

perl -ne "print;" file.txt

· -p — Perl считает, что сценарий заключен в следующий цикл (его работа имитирует редактор sed):

while (<>) {

...

[сценарий]

...

} continue {

print or die "-p destination: $!\n";

}

· -P — пропустить сценарий через препроцессор компилятора C. Это позволяет использовать директивы C вида #define и #include, а также операторы условной компиляции. После препроцессора результат поступает на ввод Perl.

· -s — разрешает разобрать ключи, переданные сценарию в качестве параметра (список [arguments], указываемый в командной строке после имени файла). Например, следующая команда печатает сообщение «Found the switch», если при старте сценарию был задан ключ -www:

if ($www) {print "Found the switch\n"};

· -S — заставляет Perl использовать переменную окружения PATH для поиска сценария.

· -T — активизирует проверку меченых данных (проверка секретности доступа). Часто требуется как составная часть при CGI-программировании.

· -u — заставляет Perl записать дамп памяти (core dump) после компиляции сценария.

· -U — разрешает Perl выполнять «небезопасные» операции (например, удаление каталогов).

· -v — выводит номер версии, подверсии и номер патча Perl, а также платформо-зависимую информацию об интерпретаторе (последняя может быть очень существенной).

· -V — подробная распечатка текущей конфигурации Perl (то есть всех конфигурационных переменных).

· -V:имя — распечатка конфигурационной переменной с указанным именем.

· -w — выводить предупреждающие сообщения (см. также следующий ключ). Рекомендуется всегда запускать Perl с этим ключом.

· -x или -xкаталог — указывает Perl, что сценарий содержится внутри сообщения. Ввод не будет обрабатываться, пока интерпретатор не встретит строчку с шаблоном !# и подстрокой perl. Конец обрабатываемого текста совпадает с концом файла или синтаксической конструкцией __END__. Если указан каталог, то Perl выполняет команду перехода к каталогу перед запуском сценария.

· -- — эти два дефиса являются необязательными. Они означают конец списка ключей, передаваемых интерпретатору.

Ключ -w и проверка синтаксиса

При работе с Perl стоит всегда задавать ключ -w. Большинство знатоков стиля языка Perl фанатично поклоняются ему. Я также рекомендую указывать этот ключ.

Ключ -w выводит предупреждающие сообщения по многим поводам. Среди них:

· имена переменных, упоминающихся только один раз,

· скалярные переменные (вроде простых переменных), которые используются до инициализации,

· переопределение подпрограмм,

· ссылки на неопределенные дескрипторы файлов,

· дескрипторы файлов, открытых только для чтения, но для которых производится попытка записи,

· значения, используемые как числа, но выглядящие иначе, чем числа,

· использование массива как скалярной переменной,

· подпрограммы с глубиной рекурсии больше 100.

Текстовый ввод и вывод с помощью стандартных дескрипторов файлов

Perl рассматривает ввод и вывод данных как потоки, а работа с этими потоками организуется через дескрипторы файлов. Дескриптор файла — это просто значение, которое в Perl соответствует файлу. Программа получает дескриптор, когда открывает файл.

 

Печать номера текущей строчки сценария и имени сценария

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

· STDIN — стандартный поток ввода.

· STDOUT — стандартный поток вывода.

· STDERR — стандартный поток вывода для сообщений об ошибках.

По умолчанию все три файла соответствуют терминалу. В этой главе (например, в следующем разделе) мы ограничимся предопределенными дескрипторами файлов, используя для вывода текста STDOUT.

Вывод текста

Чтобы вывести текст в файл (включая стандартный поток вывода STDOUT), используется команда print. Она имеет три формы:

print дескриптор список

print список

print

Если дескриптор файла не задан, используется STDOUT. Если не задан список (который может состоять и из одного элемента), Perl выводит содержимое специальной переменной $_. (Она по умолчанию используется для сохранения результатов последней операции чтения из потока ввода — см. далее раздел «Чтение потока ввода».)

Простейший пример, в котором в поток вывода отправляется слово «Hello» и символ конца строки:

print "Hello!\n";

Hello!

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

print "Hello", "there!\n";

Hello there!

Отметим, что в Perl текстовый вывод может быть довольно изощренным, благодаря специальным форматам и команде printf (см. главу 11).

Печать номера текущей строчки сценария иименисценария

Чтобы использовать номер строчки сценария, которую в данный момент обрабатывает Perl, надо сослаться на него с помощью конструкции __LINE__. Точно так же можно вывести имя файла, в котором хранится сценарий, если использовать конструкцию __FILE__. Пример:

%perl -e "print __LINE__;"

1

Повтор текста при печати

Можно повторить вывод строки несколько раз, не копируя ее в теле сценария и не используя оператор цикла. Для этого служит оператор повторения, который выглядит следующим образом:

print "Hello!\n" x 5;

Hello!

Hello!

Hello!

Hello!

Hello!

Например, вот так выводится горизонтальная черта из дефисов:

print "-" x 30;

------------------------------

Основные команды форматирования

С помощью escape-последовательностей в Perl можно выполнять некоторые команды форматирования. Escape-последовательность — это набор символов, которым предшествует обратная косая черта (\). Она особым образом обрабатывает ся внутри строки, ограниченной двойными кавычками (разница между строками, ограниченными двойными кавычками, и строками, ограниченными апострофами, рассматривается в следующей главе). Некоторые escape-последовательности приведены в табл. 1.1.

Например, вот как напечатать двойные кавычки в текстовой строке:

print "\"Hello!\"\n";

"Hello!"

Подсказка. Символы \, $ и комбинации вида @идентификатор и @{ также надо набирать с помощью escape-последовательностей, так как внутри строки, ограниченной двойными кавычками, эти символы интерпретируются особым образом (в частности, символ \ — как начало escape-последовательности.)

А вот так используется табуляция:

print "Hello\tfrom\tPerl.\n";

Hello from Perl.

Здесь с помощью символов новой строки выводится сразу несколько строчек:

print "Hello\nfrom\nPerl.\n";

Hello

from

Perl.

Это лишь базовые команды форматирования, и в Perl возможны гораздо более сложные конструкции. В этом языке всегда существует еще один способ выполнения той или иной операции с текстом, — в конце концов, он создавался именно как язык для обработки текстов.

 

Вывод неформатированного текста: встроенные документы

Таблица 1.1. Некоторые escape-последовательности

Символ Значение

\' Одиночная кавычка, или апостроф (')

\` Обратный апостроф (')

\" Двойная кавычка (")

\\ Обратная косая черта (\)

\$ Символ доллара ($)

\@ Символ at-коммерческое (@)

\e Символ escape (ESC)

\t Символ табуляции (TAB, HT)

\v Символ горизонтальной табуляции (VT)

\n Символ новой строки (LF)

\r Символ возврата каретки (CR)

\f Символ прогона страницы (FF)

\b Символ забоя (BS)

\a Символ звукового сигнала (BEL)

\033 Восьмеричный символ

\x1b Шестнадцатеричный символ

\c[ Управляющий символ (control character)

Вывод неформатированного текста: встроенные документы

Perl позволяет выводить текст в точности так, как он набран в теле сценария. Чтобы отметить начало подобного текстового фрагмента (в Perl они называются «here-documents»), используется команда <<, за которой следует некоторая метка (в нашем примере это EOD, что является сокращением от end-of-document):

print <<EOD;

This

is

a

"here"

document.

EOD

Текст, отформатированный в теле сценария, заканчивается идентификатором, указанным в его начале. (Обратите внимание, что в первой строке после идентификатора, маркирующего начало «встроенного» текста, стоит точка с запятой, а после идентификатора, маркирующего конец текста, точки с запятой нет.) В результате на экран будет выведено:

This

is

a

«here»

document.

Комментарии

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

Комментарии Perl начинаются с символа #. Perl игнорирует весь текст, идущий от символа # до конца строки. Вот пример сценария Perl-оболочки с комментариями, разъясняющими назначение кода:

#!/usr/local/bin/perl5 -w # Use Perl 5 with warnings

use strict; # Require variable declarations, etc.

my $count=0; # $count used to match {}, (), etc.

my $statement=""; # statement holds multi-line commands

local $SIG{__WARN__} = sub{}; # supress error reporting

while (<>) { # Accept input from the keyboard

chomp; # Clean-up input

while (/{|\(|\[/g) {$count++}; # Watch for {, (, etc.

while (/}|\)|\]/g) {$count--}; # Watch for }, ), etc.

$statement .= $_; # Append input to current statement

if (!$count) { # Evaluateonly if {, ( matches }, )

eval $statement; # Evaluete Perl statement

if ($@) {print "Syntax error.\n"}; # If error ...

$statement = "; # Clear the current statement

$count = 0; # Clear the counter

}

}

Подсказка. Вы можете включить прямо в тело программы документацию (POD = Plain Old Document), описывающую, как надо работать с вашей программой или модулем. Она будет игнорироваться при загрузке, но вы всегда можете извлечь ее в виде ASCII-файла или даже в виде размеченного HTML-файла с помощью утилит, входящих в состав Perl. Как это сделать, рассказывается в главе 15 (раздел «Документирование модулей»).

Чтение потока ввода

Ранее в этой главе мы видели, что для вывода текста используется функция print, — но как ввести текст? Его можно читать из стандартного потока ввода STDIN с помощью угловых скобок < и >. В следующем примере цикл while (рассматриваемый в главе 5) помогает построчно считывать вводимый пользовате лем текст, запоминать его в переменной $temp и затем выводить на экране:

while ($temp = <STDIN>) {

print $temp;

}

Если запустить этот сценарий и ввести с клавиатуры слово Hello, сценарий повторит его на экране:

Hello!

Hello!

 

Очистка введенного текста

На самом деле (как это обычно и бывает в Perl) добиться подобного эффекта можно и более простым путем. (В Perl имеется специальное жаргонное выражение: «There is more than one way to do it» — «Сделать что-либо можно несколькими способами», сокращаемое до TMTOWTDI и произносимое примерно как «Tim Toady».) Для этого придется заглянуть в следующий раздел.

Специальная переменная $_

Когда конструкция <STDIN> используется без указания, куда поместить возвращаемое значение, Perl автоматически записывает его в специальную переменную  $_. Многие функции Perl по умолчанию получают аргументы из нее (если пользователь не задал другого входного значения). Например, команда print без аргументов выведет содержимое именно $_. (Есть также масса других специальных переменных — например, $!, которая хранит информацию о последней ошибке, если та произошла. Более подробно о специальных переменных рассказыва ется в главе 9.)

На самом деле ключевое слово STDIN в угловых скобках можно опустить — для пустых угловых скобок по умолчанию предполагается дескриптор STDIN. (В Perl имеется масса правил по умолчанию, подобных этому. Это делает программы проще для экспертов, но запутаннее для новичков. Возможно, именно поэтому Perl так нравится экспертам.) Тем самым код из предыдущего раздела может быть записан как

while(<>){print;}

Это воистину краткая запись для аналогичных действий сценария

while ($_ = <STDIN>) {

print $_;

}

Очистка введенного текста

Через стандартный поток STDIN читается все, что набирается с клавиатуры или поступает из файла, включая символ новой строки в конце. Чтобы избавиться от него, можно использовать функцию chop или chomp. Вот как выглядит функция chop:

chop переменная

chop список

chop

Она отсекает последний символ в строке и возвращает его в качестве результата. Если опущено имя переменной, функция работает со специальной переменной  $_. Например, сценарий

while (<>) {

print;

}

выводит на экране содержимое потока ввода, включая символы новой строки. Если же использовать такой вариант:

while (<>) {

chop;

print;

}

то символов-паразитов новой строки не будет.

Вместо функции chop рекомендуется использовать chomp, которая вызывается аналогичным образом:

chomp переменная

chomp список

chomp

Эта функция более безопасна — она удаляет из конца строки символы, соответствующие текущему значению специальной переменной Perl $/, хранящей символ, выступающий в качестве разделителя входных записей. По умолчанию используется символ новой строки \n. Функция chomp возвращает число удаленных символов. Обычно она используется для удаления символа новой строки из записи, прочитанной через поток ввода. Если отсутствует имя переменной, обрабатывается $_.

Как избежать немедленного закрытия окна MS-DOS в Windows 95/98/NT

Если вы используете Perl для Windows 95/98 или Windows NT то, очевидно, отметили одну раздражающую деталь. После двойного щелчка по имени файла с расширением .pl появляется окно сеанса MS-DOS; в нем выполняется сценарий, но немедленно по его завершении окно закрывается, не оставляя никакого шанса просмотреть выведенную информацию.

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

print "Hello!\n";

print "Press <Enter> to continue...";

<STDIN>

Естественно, <STDIN> можно заменить просто на <>:

print "Hello!\n";

print "Press <Enter> to continue...";

<>