В главе 11 вы изучили, как создавать скрипты CGI, ис-
пользуя языки программирования C и C++. Однако
наиболее широко
применяемым языком для написания скриптов
является Perl. Эта гла-
ва посвящена языку Perl и его использованию. После
того как вы
научитесь программировать, используя Perl, вы
сможете использо-
вать его для написания скриптов, с помощью
которых решаются раз-
нообразные задачи программирования для Internet и Web.
Особый
упор будет сделан на тех особенностях, которые
используются при
написании CGI-скриптов. Если вы никогда не
программировали ранее
на языке Perl, используйте эту главу как отправную
точку в его
освоении. Концепции, с которыми вы познакомитесь
в этой главе,
научат, как писать профессиональные скрипты на
языке Perl. В гла-
ве рассматриваются не только основы
программирования на Perl, но
также и несколько других аспектов. К моменту
окончания чтения
главы вы будете в состоянии усвоить следующие
ключевые концепции
? Perl является интерпретируемым языком
программирования, спе-
циально ориентированным на обработку текста. ?
Программисты час-
то называют программы на языке Perl скриптами. ?
Используя Perl,
программисты создают CGI-формы ? Perl поддерживает
операции с
файлами и с базами данных. Это делает его хорошо
приспособленным
для хранения и извлечения информации в
соответствии с потребнос-
тями пользователей Web. ? Perl снабжается отладочной
программой,
с помощью которой вы тестируете код Perl.
PERL КАК ЯЗЫК ПРОГРАММИРОВАНИЯ
Perl (Practical Extraction and Report Language ) является
переносимым, интерпретируемым языком, идеально
приспособленным
для многочисленных приложений по обработке
текста. Perl поддержи-
вает структурированные программные конструкции,
как и большин-
ство языков программирования высокого уровня, и
предлагает богат-
ство встроенных возможностей, накопленных им за
годы эволюции
среде UNIX. Perl является бесплатным программным
обеспечением.
Его можно получить платно, и книга
<Web-программирование> служит
его бесплатному распространению). Фактически, Perl
версии 5
имеется, на CD-ROM, прилагаемом к этой книге. Эта
глава, однако,
посвящена в первую очередь концепциям Perl версии
4, которая пол-
ностью совместима с версией 5 и широко
используется на Web.
ИСТОРИЯ PERL
Отцом языка Perl является Ларри Вол (Larry Wall). Он
разра-
ботан в 1986 году для создания отчетов о содержании
многочислен-
ных текстовых файлов в среде UNIX. Поскольку
существующие сред-
ства не подходили для решения такой задачи, Вол
(Wall) изобрел
новое средство для ее решения. Название Perl
oзнaчает практичес-
кий язык для извлечения и составления отчетов
(Practical
Extraction а Report Language). Вол продолжал добавлять
различные
возможности к Perl и сделал его доступным для
общего пользования.
Популярность Perl возрастает до сих пор, и он стал '
любленным
средством многих программных пакетов. Умение
программировать на
Perl имеет возрастающую важность при составлении
резюме.
PERL - ИНТЕРПРЕТИРУЕМЫЙ ЯЗЫК ПРОГРАММИРОВАНИЯ
Perl является интерпретируемым языком. Это
означает, что
программы, написанные на Perl, обычно исполняются
путем вызова
интерпретатора Perl и переда" ему списка команд,
из которых сос-
тоит программа. Поскольку интерпретатор тает и
исполняет команды
Perl именно таким образом, разработчики часто
называют программы
на Perl скриптами. Если вы вышли из мира UNIX-систем,
то, вероят-
но, знакомы со многими типам; скриптов, такими как
скрипты shell,
скрипты sed и т. д. В таком случае вы, вероятно , в
состоянии
оценить полезность и мощность языка, основанного
на скриптах.
Если вы пришли из мира DOS и Windows, то пакетные
(.BAT)-файлы
или программы на языке BASIC приходят на ум всякий
раз, когда вы
думаете об интерпретируемых скриптах. Если вы
представляете себе
файлы скриптов наподобие пакетных файлов MS-DOS, то
вы, возможно,
скептически относитесь к использованию
скриптов, за исключением
самых простейших задач. Однако если вы
придерживаетесь непредвзя-
того взгляда на вещи, то в скором времени сможете
оценить всю
мощь Perl. .
СРАВНЕНИЕ PERL И ЯЗЫКОВ ПРОГРАММИОВАНИЯ С/С++
Структура Perl очень напоминает структуру языка
программиро-
вания С и на первый взгляд выглядит так же, как
программа С. Все
операторы С представлены в 1 Perl, а управляющие
структуры, та-
кие как if или for, имеются на языке Perl в несколько
измененном
виде. Чего не достает в Perl, так это указателей,
структур и ти-
пов, определяемых пользователем. Место языка С в
программирова-
нии неоспоримо, но не следует думать, что
С-программа всегда луч-
ше, чем эквивалентная программа на языке Perl. Как и
у всякого
средства, у Perl и у С есть свои области применения,
к которым
они лучше всего приспособлены. Надо хорошо знать
оба языка, что-
бы представлять, когда предпочтительнее
использование одного из
них.
БОГАТСТВО ВОЗМОЖНОСТЕЙ ЯЗЫКА PERL
Perl предоставляет разработчику широкий спектр
возможностей
для создания кратких и эффективных программ.
Ниже приведены неко-
торые наиболее замечательные черты Perl. Далее в
главе вы позна-
комитесь с использованием каждой из них: ?
Ассоциативные массивы,
которые индексируются программами с
использованием нецелых клю-
чей ? Автоматическое преобразование типов между
целыми числами,
числами с плавающей точкой и строками ?
Автоматическое преобразо-
вание размера массивов ? Функции для
преобразования бинарных дан-
ных ? Широкая поддержка так называемых
регулярных выражений, ко-
торые программы используют для поиска, замены и
других операций,
связанных с разбором текста ? Функции
вывода/ввода файлов ? Фун-
кции форматированного вывода, наподобие функции
С, с добавлением
к ним способности генерации отчетов на основе
шаблонов (template)
? Полный набор.операторов С, с добавлением также
операций по
сравнению строк ? Функции для обработки списков,
которые поддер-
живают стеки, очереди и другие данные списочных
типов ? Функции
системного сервиса ? Богатый набор операторов и
структур управле-
ния, включая подпрограммы
ИСПОЛЬЗОВАНИЕ PERL
Чтобы разобраться, как использовать Perl,
необходимо проана-
лизировать коды написанные на нем. Самый простой
путь познако-
миться с языком Perl состоит в изучении коротких
примеров. Сле-
дующий раздел основан на коротких примерах для
того, чтобы ввес-
ти вас в курс дела. После того как вы поймете
основы техники
программирования на языке Perl, вы сможете писать
на нем CGI-
скрипты.
ИСПОЛЬЗОВАНИЕ PERL КАК ФИЛЬТРА ДАННЫХ
Средства UNIX-систем в значительной мере основаны
на концеп-
ции о том, что программа служит фильтром данных,
поток которых
поступает на вход, а отфильтрованные данные - на
выход. Таким об-
разом, программа-фильтр отбрасывает
нежелательные данные. MS DOS
также поддерживает концепцию фильтра данных.
Утилита grep в сре-
де UNIX представляет собой классический пример
фильтра данных.
Эта утилита сканирует входной поток данных в
поиске строк, кото-
рые соответствуют заданному шаблону. Программа
направляет на вы-
ход те строки, которые соответствуют этому
шаблону. Она от-
фильтровывает, отбрасывает строки, не
удовлетворяющие шаблону.
Perl идеально подходит для построения фильтров
данных. Действи-
тельно, вы можете создать простую версию утилиты
grep, используя
следующий короткий скрипт на языке Perl:
$pattern = shift(@ARGV); # берет командную строку
while (<>)
{ # читать строку из входного потока
print if (/$pattern/); # output line if it matches
}
В этом случае скрипт просто просматривает
входные данные
строка за строкой. Если строка содержит текст,
определенный пер-
вым аргументом командной строки, то программа
печатает такую
строку. Не беспокойтесь, если написанный текст
скрипта вам пока
непонятен. В этой главе вы найдете описание всех
операторов по-
добного типа программ на языке Perl.
ИСПОЛЬЗОВАНИЕ ЯЗЫКА PERL КАК ШЛЮЗА БЕЗОПАСНОСТИ
Вопросам безопасности придается большое
значение как в прог-
раммировании CGI, так и при решении других задач,
связанных с
программным обеспечением для сетей. Часто бывает
необходимо защи-
тить файлы и другие ресурсы системы от угрозы со
стороны пользо-
вателей, которая может проистекать от их
неаккуратности или даже
злого умысла. Это особенно важно для Web-серверов,
а также дру-
гих серверов, таких как FTP-сервер, которые
подключены к
Internet, где наличие злоумышленных пользователей
хорошо извес-
тно. Одним из путей защиты системы от атак таких
злоумышленников
служит создание шлюзов безопасности, через
которые пропускаются
входные данные. В этом случае только данные,
оцененные шлюзовой
программой как безопасные, передаются в систему.
Традиционно
большая часть серверов Internet исполняется под
системой UNIX и
написана на языке С. Неверное использование
программистами указа-
телей на языке С ведет к нарушению безопасности
работы системы.
Одним из достоинств Perl, существенным при
написании надежных
шлюзовых программ, служит тот факт, что
переменные строкового ти-
па изменяют свою длину автоматически в
зависимости от потребнос-
ти. Строковые переменные содержат столько
символов, сколько им
присваивает скрипт. Perl не позволяет программе
писать данные в
одну переменную таким образом, чтобы нарушить
целостность данных
другой переменной. Имеется также специальная
версия языка Perl,
которую называют taintperl, в которой осуществляется
проверка за-
висимостей между данными и предотвращается
выполнение системой
команд по передаче данных серверу от источника,
не заслуживающе-
го доверия. Если испорченные или некорректные
данные поступают на
вход программы taintperl, то она помечает все
значения командной
строки, переменных окружения и входные данные
как испорченные,
предотвращая их дальнейшую передачу серверу и
возникновение фа-
тальной ошибки.
FRONTEND-ПРОГРАММЫ ДЛЯ СВЯЗИ С БАЗОЙ ДАННЫХ
Утилита типа frontend для базы данных представляет
собой
программу, которая упрощает доступ к серверу
базы данных для ос-
тальных программ. Такая программа обрабатывает
запрос пользовате-
ля к базе данных и на этой основе формирует свой
запрос к базе
данных с параметрами, необходимыми для доступа к
данным на серве-
ре. Frontend-программа может также обрабатывать
результаты запро-
са, формировать ответ и посылать его обратно
пользователю. Как вы
узнаете, программисты создают простые
приложения для баз данных
исключительно на языке Perl, причем не возникает
необходимости в
специальном сервере базы данных. Perl имеет
встроенные возможнос-
ти для отображения ассоциативных массивов
(обсуждаемых дальше в
этой главе) на файл базы данных. В результате
доступ к файлу ба-
зы данных в рамках скрипта Perl так же прост как и
доступ к эле-
ментам массива, поскольку ввод/вывод в файл
является прозрачным
для скрипта. Для более сложных приложений на
основе баз данных
Perl может выполнять роль связующего звена с
сервером базы дан-
ных и функционировать как Frontendпрограмма для базы
данных. Нес-
колько специальных версий языка Perl было создано
для расширения
поддержки конкретных серверов баз данных.
Например, oraperl обес-
печивает возможность доступа к серверам баз
данных Oracle.
ИСПОЛЬЗОВАНИЕ ЯЗЫКА PERL ДЛЯ НАПИСАНИЯ CGI-
CКРИПТОВ.
Как вы узнали из предыдущей главы, CGI
обеспечивает узлам
Web вoзмoжнoсть интерактивной работы с клиентскими
программами, в
качестве которых обычно выступает броузер. Во
многих случаях уз-
лы используют скрипты CGI для доступа к базам
данных в тех слу-
чаях, когда клиент и сервер должны обмениваться
данными.
Использование CGI позволяет пользователю
получать доступ к базе
данных на Web, используя обычный Web-броузер.
CGI-скрипт читает и
обрабатывает содержание НТМL-форм, устанавливает
соединение с ба-
зой данных, посылает ей запросы, обрабатывает
результаты ответов,
формируя на их основе новый НТМД документ, и
затем посылает его
обратно пользователю. Кроме того, все эти шаги
должны быть сдела-
ны так, чтобы обеспечить безопасность сервера.
ЗНАКОМСТВО С ЯЗЫКОМ PERL
Хочется верить, что вас удалось убедить в
необходимости хо-
тя бы рассмотреть использование языка Perl для
написания скрип-
тов CGI. В следующих разделах вы узнаете, как
запускать Perl на
исполнение и как создавать полезные скрипты на
языке Perl. Благо-
даря сходству Perl и С, в этой главе мы сосредоточим
внимание на
том, что объединяет их, и на их различиях. Больше
внимания в гла-
ве будет уделено различию между этими языками.
<HELLO WORLD> НА ЯЗЫКЕ PERL
Большинство учебников по языкам
программирования начинается
с простейшей программы, которая выводит текст
<Hello World>. В
соответствии с этой традицией мы приводим нашей
книге несколько
примеров программ <Hello World>. Следующий код
служит для вывода
на экран сообщения <Hello World> три раза, используя
три различ-
ных способа:
# Три способа как сказать <Hello World>
printf("Hello world\n");
printf("%s\n",'Hello world');
print "Hello World", "\n"
Первая строка представляет собой комментарий. На
языке Perl
знак диез (#) означает комментарий. Когда Perl
находит этот знак,
он игнорирует весь текст, начиная с него и до
конца строки. Знак
диез служит единственным способом ввести
комментарии на языке
Perl. В отличие от С здесь нет конструкции, которая
сразу бы оп-
ределяла несколько строк комментариев. На первый
взгляд функция
printf выглядит так же, как в языке С. Однако вы
можете заметить,
что программа не содержит функции main. Хотя
скрипты поддержи-
вают подпрограммы (аналогичные функциям С),
скрипт не определяет
раздела, который бы содержал тело функции main.
Вместо этого ин-
терпретатор Perl сразу начинает исполнение
скрипта с первого вы-
ражения в файле. Второе выражение, содержащее
функцию printf,
опять-таки выглядит аналогично своему
использованию в языке С, за
исключением того, что вторая строка аргументов
заключена в оди-
нарные кавычки ('') в противоположность двойным
(""), используе-
мым в С. В языке Perl строка в двойных кавычках
означает опреде-
ленный род преобразования. Например,
интерпретатор Perl преобра-
зует выражение новой строки в двойных кавычках
"\n" в символ но-
вой строки. Скрипт Perl использует одинарные
кавычки для включе-
ния строковых литералов, т. е. строковых
выражений, как это напи-
сано выше. Например, Perl напечатает выражение в
одинарных кавыч-
ках ('\n') как два знака ('\') и 'n', а не как знак
перехода на
новую строку. Наконец, последняя строка кода
программы содержит
функцию print, которой нет в языке С. В этом случае
наиболее по-
лезная черта этой функции заключается в
отсутствии скобок. Оказы-
вается, что вы можете всегда включать скобки в
состав функции
языка Per]. Однако в большинстве случаев
необходимости в них нет.
Perl требует включения скобок только в том случае,
если без них
выражение оказывается не полностью
определенным, двусмысленным.
Тем не менее, включение скобок в код
соответствует хорошей тради-
ции, и вам не следует отказываться от нее.
УСТАНОВКА PERL
Теперь настало время попробовать работать с
языком Perl не-
посредственно. Если у вас не установлен Perl на
вашей системе, то
необходимо сделать это. Обратитесь к файлу Perl.txt
на CD-ROM,
который входит в комплект книги. Далее полагаем,
что Perl пра-
вильно установлен. Наберите команду для запуска
скрипта Perl,
аналогичную следующей:
C:\PERL>perl script-name <ENTER>
Например, создайте файл с именем hello.pl, содержащий
пока-
занную ниже строку:
Print "Hello world\n"
Далее в командной строке наберите следующую
команду:
C:\PERL>perl hello.pl <ENTER>
На экране вы увидите следующий текст:
Hello World
Как уже говорилось, если вы используете
UNIX-систему, то
можно вызвать скрипт Perl таким же образом, как
другую самостоя-
тельную программу. Для того чтобы начать,
отредактируйте файл
так, чтобы первая строка была аналогична
представленной ниже:
#!/usr/bin/perl
print "Hello world\n"
В этом случае первая строка указывает системе,
что необходи-
мо запустить скрипт, используя Perl. Можно видеть,
что эта стро-
ка является комментарием и это не случайно, так
что Perl, проиг-
норирует ее. Тем не менее, большинство UNIX
командных скриптов
shell просмотрят два первых символа в любом
исполняемом скрипте.
Если первыми символами служат #!, то shell будет
использовать ос-
таток строки в качестве команды для запуска
скрипта. В данном
случае такой командой является /usr/bin/perl. Shell
пересдаст имя
скрипта Perl автоматически. Для того чтобы
запустить скрипт,
необходимо запустить команду chmod для того, чтобы
указать скрип-
ту на файл, который необходимо выполнить
(например, chmod + х
hello.pl). В зависимости от программы shell, также может
потребо-
ваться набрать команду rehash для того, чтобы
указать программе
shell, что вы добавили новую команду. Возможно,
также потребует-
ся модифицировать путь к Perl, если он не
инсталлирован в подка-
талоге /usr/bin вашей системы.
Примечание: Большинство скриптов Perl используют в
качестве рас-
ширения.р1, но это необязательно. Если вы
запускаете скрипт Perl
как отдельную программу, то, возможно, более
удобным будет вооб-
ще опустить расширение.
ИСПОЛЬЗОВАНИЕ ОТЛАДЧИКА PERL
Может показаться преждевременным говорить
сейчас об отладчи-
ке Perl. Но использование отладчика может
оказаться исключи-
тельно полезным при изучении языка Perl. С ним вы
можете легко
испытать все программы, которые приведены в этой
главе в качес-
тве примеров. Фактически можно внести любое
выражение Perl непос-
редственно в отладчик, используя его в качестве
интерактивного
Perl. Таким способом можно ознакомиться со многими
возможностями
языка, что намного проще, чем создавать и
запускать полные скрип-
ты. Отладчик Perl встроен в сам Perl. Можно запустить
отладчик,
используя ключ -d в командной строке следующим
образом:
C:\PERL> Perl -d hello.pl <ENTER>
В таком случае Perl загрузит скрипт hello.pl и начнет
отлад-
ку. Если вы используете UNIX-систему, то можете
поместить коммен-
тарий #!/usr/bin/perl -d в самом начале скрипта Perl. Если
хоти-
те загрузить Perl с отладчиком без загрузки
скрипта, то можете
использовать следующую команду: С: \> Perl -de 0
<ENTER> В таком
случае аргумент командной строки -d указывает Perl
на необходи-
мость вызова отладчика, а аргумент -e 0 заставляет
выполнить Perl
скрипт, состоящий из 0 строк. Поскольку скрипт 0 не
существует,
то Perl просто запустит отладчик. Если Perl
установлен на вашу
систему корректно, то на экране вы увидите
следующие данные, ко-
торые говорят, что вы находитесь в отладчике:
Loading DB routines from $RCSfile: perldb.pl,v $$Revision: 4.0.1.3
$$Date: 92/06/08 13:43:57 $
Emacs support available.
Enter h for help.
main '(p1000159:1):
DB<1>
Если Perl выводит ответ, но указывает на ошибку,
такую как
Can't locate perldb.pl @INC, то, значит, Perl установлен в вашей
системе некорректно. В таком случае прочитайте
readme-файлы, ко-
торые сопровождают вашу версию Perl. В отладчике
можно набрать
любое выражение Perl, и он немедленно его исполнит.
Дополни-
тельно можно использовать следующие команды
отладчика: ? h - рас-
печатать в качестве подсказки список команд
отладчика ? n - вы-
полнять до следующего выражения ? <CR> -
повторить последнюю ко-
манду n или s ? p выражение - сокращение для команды
print выра-
жение ? q - окончить работу ? r - исполнять до выхода
из подпрог-
раммы ? s - один шаг по скрипту (со входом в
подпрограмму)
Например, следующая команда отладчика
использует функцию
print для того, чтобы вывести на экран сообщение Hello
World:
DB<1> prinf "Hello World\n"; <ENTER>
Hello World
DB<2>
Используя отладчик с помощью команды р, можно
вывести на эк-
ран любое выражение. Для упрощения набора в
отладчике можно опус-
кать точку с запятой в конце выражения, поскольку
отладчик доба-
вит ее для вас. Наконец, отладчик всегда
переходит на новую стро-
ку для новой команды. Следующий код иллюстрирует
использование
команды р: <ENTER>
DB<2> р "Hello World\n" <ENTER>
Hello World
DB<3>
Как можно видеть, всякий раз, когда вы набираете
команду от-
ладчика, счетчик отладчика увеличивается на
единицу, что находит
отражение в его строке DB.Читая дальше эту главу,
вам, вероятно,
стоит запустить отладчик, чтобы иметь
возможность набирать в нем
примеры и работать с языком Perl интерактивно.
Примечание: Для того, чтобы ввести выражение из
многих строк в
отладчик (debugger), необходимо использовать символ
продолжения
<\> конце каждой строки.. Иначе отладчик
сообщит о синтаксичес-
кой ошибке.
Следующая команда иллюстрирует использование
символа продол-
жения при работе с отладчиком:
В этом случае для вывода чисел от 0 до 9
использовался цикл
for, который будет подробно рассмотрен в этой
главе.
ТИПЫ ДАННЫХ В PERL
Типы данных используются в программах при
объявлении пере-
менных. Короче говоря, тип данных определяет то
множество значе-
ний, которые может принимать переменная, а также
набор операций,
которые программа может выполнять с ней. В языке
Perl данные мо-
гут быть числом или строкой символов. Одно
значение называется
скалярной величиной или просто скаляром. Ниже
приведены примеры
скалярных значений, которые используются в языке
Perl: ? Десятич-
ные: 127 или 127.0 или 1.27Е2 ? Шестнадцатиричные: Ox7F или
0x7f
? Восьмеричные: 0177 (первый 0 указывает, что
используется
восьмеричное число) ? Строка: "Hello World\n" или
'Hello World'
Например, следующая команда использует отладчик
Perl для того,
чтобы вывести число 0177 восьмеричной системы,
соответствующее
числу 127 десятичной:
DB<4> р 0177 <ENTER>
127
Perl переводит данные в свой внутренний формат.
Когда Perl
печатает восьмеричные или шестнадцатиричные
значения, он сначала
переводит их в десятичный формат, как было
показано.
Примечание: Как вы узнаете, скрипт Perl позволяет
использовать
функцию printf для того, чтобы выводить, значения в
вызываемом
формате, в таком как восьмеричный или
шестнадцатиричный.
В качестве внутреннего представления всех чисел
использует-
ся формат с плавающей запятой двойной точности
(double). Иными
словами, среди внутренних форматов нет
целочисленного. Тем не ме-
нее, в большинстве случаев вы можете не обращать
на это внимания,
и Perl сделает все сам как надо. Например, если вы
используете
величины в контексте, где только целочисленные
значения имеют
смысл, Perl сам автоматически усечет число.
Примечание: Если вы программируете на С и
использовали целочис-
ленное деление с усечением целых чисел
автоматически, то, прог-
раммируя на языке Perl, надо не забыть выполнить
усечение вруч-
ную, используя функцию int().
Следующая команда иллюстрирует, как Perl
обрабатывает числа
целого типа и с плавающей запятой:
Точно так же, как Perl преобразует числа с
плавающей запя-
той в целые числа: когда скрипт использует
целочисленные значе-
ния, он также преобразует числа в строки и
наоборот, когда такое
преобразование имеет смысл. Например, если
скрипт использует чис-
ла в контексте, где только строки имеют смысл,
например, при сое-
динении строк, он конвертирует числа в строки.
Аналогичным обра-
зом, если требуется использовать строки там, где
только числа
имеют смысл, то Perl конвертирует их в числа.
Работая со скрипта-
ми Perl, обычно не надо беспокоиться о внутреннем
представлении
скалярных величин. Perl поддерживает также
концепцию булевых зна-
чений, но не имеет для их описания специального
типа. Как и в С,
численное значение рассматривается истинным,
если оно не равно
нулю. Дополнительно строковое значение
рассматривается как истин-
ное, если оно не равно '' или '0'. Некоторые булевы
операторы,
такие как <>> (больше), возвращают единицу в
качестве значения
<истинно> и нуль - в качестве <ложно>. Тем
самым, ваш скрипт дол-
жен просто рассматривать ненулевые величины как
строчного типа,
так и числового в качестве булева значения
<истинно>. Скрипты
Perl могут группировать скалярные величины вместе
и создавать
список (list). Если скрипт хранит список в какой-то
переменной,
то эта переменная становится массивом (array).
ПЕРЕМЕННЫЕ
Perl поддерживает три типа переменных: скаляры,
массивы и
ассоциативные массивы. Как и в языке С, имена
переменных пишутся
с различением строчных и заглавных букв. Таким
образом, имена
VAR, Var и var описывают различные переменные. Скрипт
может иметь
скалярную переменную под именем var и
переменную-массив, также
названную var. Они будут различаться в языке Perl в
соответствии
с контекстом.
Примечание: Переменные Perl нетипизированы, как
это делается и в
С. Например, скалярная переменная может
содержать любой тип ска-
ляра, и приведение типов осуществляется
автоматически. Также, как
вы могли уже заметить, переменные на языке Perl
необязательно
должны быть объявлены. Если переменная не
объявлена, то Perl рас-
сматривает ее как глобальную. Ниже вы
познакомитесь с объявле-
нием переменных и их областью видимости.
СКАЛЯРНЫЕ ПЕРЕМЕННЫЕ
Как отмечалось, скалярная переменная может
содержать един-
ственное значение. В языке Perl имена скалярных
переменных всег-
да начинаются со знака ($). В еле дующем выражении
скалярной пе-
ременной $age присваивается значение 35, а
переменной $name -
строковое значение <Bob>. Затем используется
функция print для
вывода значения каждой из переменных:
Если вы сохраните эти выражения в файле под
именем
SCALAR.PL, то сможете запустить программу следующим
образом:
C:\PERL> Perl SCALAR.PL <ENTER>
Bob is 35
МАССИВЫ
Как было сказано выше, массивы представляют
собой перемен-
ные, принимающие в качестве значения список из
скалярных величин.
Следующий текст программы на языке Perl
иллюстрирует объявление
переменных типа массив и их инициализацию:
print(@days); # выведет 'SunMonTueWedThuFriSat'
print($days[4]); # выведет 'Thu'
@weekdays = @days[1..5]; # значение ('Mon','Tue','Wed','Thu','Fri')
@emptylist = (); # постой список
Ссылка на переменные типа <массив> обычно
начинается со зна-
ка (@) и сопровождается значениями в квадратных
скобках ([ ]).
Как и в программировании на языке С, индексами
массивов для
скриптов всегда являются переменные целого типа,
которые обычно
начинаются с нулевого значения. Вы увидите
исключения из этих
двух правил в примерах, которые будут
объясненены в этой главе.
Третье выражение ($days[4]) служит примером массива,
который ссы-
лается на скалярное значение. Поскольку он
содержит только один
элемент, результирующее значение представляет
собой скаляр. Если
использовать знак ($) вместо знака (@), то скрипт
будет ссы-
латься на скалярную величину. Это замечание
является очень важ-
ным. Квадратные скобки указывают, что скрипт
ссылается на массив.
Знак $, в свою очередь, означает ссылку на
скалярную величину.
Инициализация массива @weekdays осуществляется
путем выборки час-
ти массива @days. В предыдущем примере массив @days
использовал-
ся без индекса. Когда индекс опущен, Perl ссылается
на весь мас-
сив. Аналогичным образом, в предыдущем примере
массив @days ини-
циализировался списком литералов. Кроме того,
что массиву могут
присваиваться в качестве значений литералы,
скрипт может также
присваивать массивам значения переменных или
даже других масси-
вов, как показано ниже:
Если скрипт использует переменную типа массив в
контексте
скаляра, то значением служит число элементов
массива. Скалярным
контекстом является такой контекст, где только
скалярные значе-
ния имеют смысл. Например, следующее выражение
использует скаляр-
ный контекст для массива stuff для того, чтобы
определить число
элементов содержащееся в массив. Если число
элементов, больше или
равно 2, то скрипт выдает сообщение и заканчивает
исполнение:
(@stuff >= 2) || die "Too much stuff! \n";
Функция die служит директивой языку Perl закончить
выполне-
ние и выдать при этом указанное сообщение. Если
сообщение не со-
держится, то функция просто заканчивает
выполнение скрипта. Perl
также поддерживает специальную конструкцию $#
переменная, кото-
рая возвращает последнее значение индекса в
массиве. Например,
следующее выражение for использует $[ для того,
чтобы определить
начальное значение индекса массива, и $# для
определения послед-
него из элементов массива. При этом с помощью
выражения for выво-
дятся значения каждого из элементов:
Записанный цикл for можно заменить следующим
эквивалентным
выражением:
Print @stuff;
РОЛЬ КОНТЕКСТА АЛЯ ПЕРЕМЕННЫХ СКАЛЯРНОГО И
ВЕКТОРНОГО ТИПА
Отметим, что оператор построения списка (,)
выглядит точно
так же, как оператор (,) последовательного
вычисления (sequential
evaluation). Какой из операторов используется, зависит
от контек-
ста, в котором он появляется, в частности,
является ли перемен-
ная скаляром или массивом. Perl использует
конструирование спис-
ков в контексте массивов и последовательное
вычисление для скаля-
ров. Рассмотрим следующие выражения:
@an_array = (1,2,3,4,5);
$a_scalar = (1,2,3,4,5);
В первом выражении инициализируется массив, в то
время как
второе выражение устанавливает значение
скалярной переменной
$a_scalar равным 5, отбрасывая первые четыре величины.
Рассмот-
рим два следующих выражения:
print $assoc{1,2};
print @assoc{1,2};
В первом случае будет напечатано одно значение
ассоциативно-
го массива с двумя ключами, в то время как во
втором будут напе-
чатаны два значения ассоциативного массива с
одним ключом. Из
двух следующих выражений первое копирует список,
тогда как вто-
рое присваивает скалярной величине значение,
равное размеру мас-
сива:
@x = @list;
$x = @list;
АССОЦИАТИВНЫЕ МАССИВЫ
Ассоциативные массивы аналогичны обычным
массивам в том от-
ношении, что они представляют собой список
скалярных переменных.
Различие заключается в том, что массив должен
использовать цело-
численные значения в качестве индексов при
выборе элементов мас-
сива, тогда как ассоциативный массив может
использовать величины
любого типа для выбора элементов массива.
Индексные величины для
ассоциативного массива называются ключами.
Рассмотрим следующие
примеры:
for $name (keys(%ages))
{
print "$name is $ages{$keys}\n";
}
Как можно видеть, программа присваивает значения
переменной
'$,' (скалярная переменная, именем которой
является запятая).
Скрипт использует это выражение для того, чтобы
при дальнейшем
использовании оператора print выходные данные не
сливались между
собой. Далее в этой главе обсуждаются
специальные переменные, та-
кие как '$,'. Ассоциативные массивы
идентифицируются с помощью
фигурных скобок. Так же как с массивами, при
ссылках на ассоциа-
тивный массив целиком индексы не используются.
Например, ссылка
@ages{'Bob', 'Mary'} использует индексы в скобках, что
указывает
на ассоциативный массив. Префикс @ указывает на
то, что речь идет
о массиве. Аналогичное использование знака
доллара перед масси-
вом указывает, что используется скалярная
величина.
Примечаиие: Если два ключа заданы, то вместе со
знаком @ эта го-
ворит о том, что речь идет о части ассоциативного
массива и ре-
зультат должен быть в виде списка. Такое
выражение эквивалентно
#ages{' Bob'}, #ages{'Mary'}. которое имеет своим значением
вели-
чину (35, 25).
Выражение print keys(%ages) вызывает оператор keys,
который
возвращает полный список ключей ассоциативного
массива. Ссылка
%ages со знаком процента в качестве префикса
означает, что ссыл-
ка относится ко всему ассоциативному массиву.
Обратите внимание,
что цикл for ссылается на переменные, заключенные
в двойные ка-
вычки. Наконец, последний из рассмотренных
примеров также ис-
пользует оператор keys и вводит цикл for для
распечатки всех со-
четаний ассоциативного массива. Цикл for
ссылается на переменные,
заключенные в двойные кавычки. Perl, в свою оче
редь, заменит
значения, на которые ссылаются переменные, в то
время, когда бу-
дет анализировать строку. Программисты называют
этот процесс под-
становкой переменной или интерполяцией.
Примечание: Perl не интерпретирует переменные,
содержащие строки
в одинарных кавычках.
ОПЕРАТОРЫ PERL
В то время как типы данных и переменных языка Perl
значи-
тельно отличаются от соответствующих типов
языка С, операторы и
выражения Per] должны вам показаться гораздо более
знакомыми. Все
операторы С присутствуют в языке Perl, за
исключением операторы
приведения типов (type), операторы обращения к
содержимому указа-
теля *ptr и оператора выбора члена структуры var.member
или
var->member. Кроме того, в языке Perl реализовано много
новых
операторов для использования в таких операциях
как сравнение и
обработка строк.
АРИФМЕТИЧЕСКИЕ ОПЕРАТОРЫ
Арифметические операторы действуют на числовые
значения, и
их результатом является число. Если выражение
включает строковые
операнды, то Perl конвертирует строковые значения
в числовые пе-
ред тем, как оценить выражение. Perl выполняет
преобразование
строк в числа подобно тому, как это делает
функция atof()языка С
в библиотеки времени выполнения. В настоящее
время Perl поддержи-
вает следующие арифметические операторы: ? +
сложение ? - вычита-
ние или изменение знака ? * умножение ? / деление
(только для чи-
сел с плавающей запятой) ? % взятие по модулю
(только для цело-
численных значений)
Рассмотрим примеры следующих арифметических
операций языка Perl:
Примечание: В языке Perl оператор деления всегда
имеет результа-
том 4ucw с плавающей точкой, а результатом взятия
одного числа по
модулю другого является целое число и причем
предварительно оба
операнда преобразуются к целому типу.
Рассмотрим следующую операцию взятия по модулю:
print (7.9 % 3.6); # выведет 1 то же (7 % 3) = 1
Perl также поддерживает операторы инкремента и
декремента:
? ++ декремент в префиксной или постфиксной форме
? - инкремент в префиксной или постфиксной форме
Рассмотрим примеры операций инкремента и
декремента:
$x = 4;
++$x;
print $x; # выведет 5
$y = $x-; # уменьшит x после присвоения y значения x
print "$y $x" # выведет 5 4
Наконец, Perl обеспечивает арифметический
оператор для воз-
ведения в степень (**). Рассмотрим следующие
примеры использова-
ния операции возведения в степень:
$x = 2 ** 3; # результат 8
$x = 2 ** 0.5; # квадратный корень из 2
$x = -2 ** -3; # 1/(-2 в кубе), результат -1/8 (-0.125)
ПОБИТОВЫЕ ОПЕРАТОРЫ
Побитовые операторы воздействуют на бинарное
представление
целых чисел и имеют целочисленный результат.
Если операндом яв-
ляется строка или дробное число, Perl
предварительно преобразует
его в целое число, обрабатывает операнд,
используя 32-битное
представление. Все побитовые операторы С
представлены в языке
Perl: ? | побитовое ИЛИ ? & побитовое И ? ^ побитовое
исключаю-
щее ИЛИ ? ~ побитовая инверсия ? << сдвиг влево ?
>> сдвиг вправо
Так же как в С, поведение операторов сдвига
вправо зависит от
реализации язы ка в случае, если операнд является
отрицательным.
ОПЕРАТОРЫ СРАВНЕНИЯ
Операторы сравнения сравнивают величины двух
операндов. Так
же как при работе с арифметическими операторами,
Perl преобра-
зует строчные операнды в численные перед тем, как
выполнять срав-
нение. Для того чтобы позволить скрипту
сравнивать строки, кото-
рые не являются числами, Perl имеет дополнительные
операторы
строкового сравнения. Эти операторы сравнивают
строки, используя
величины ASCII. Если численное значение задано как
операнд при
сравнении строк, оно сначала преобразуется в
строку. Таблица 12.1
перечисляет операторы сравнения:
Число Строка Значение
= = eq равно
!= nе не равно
> gt больше чем
< it меньше чем
>= gе больше или равно
<= lе меньше или равно
<=> cmp не равно (результат со знаком)
Табл. 12.1. Операторы сравнения языка Perl
Результатом операции сравнения является
единица, если срав-
нение истинно и нуль в противном случае. Однако
последняя опера-
ция (<=> или cmp) может возвращать значения -1, 0
или 1 в зависи-
мости от того, является ли значение первого
операнда меньше, чем
второго, равным ему или большим.
Примечание: Оператор cmp языка Perl ведет себя,
аналогично фун-
кции Strcmp() библиотеки времени выполнения языка С.
Рассмотрим следующий пример сравнения:
$x = 5; # x равно 5
print ($x < 4); # если false, то выведет 0
ЛОГИЧЕСКИЕ ОПЕРАТОРЫ
Логические операторы анализируют булевы
выражения и возвра-
щают значения <истинно> или <ложно> в
качестве результата. Perl
обрабатывает операнды логических операций как
булевы величины, т.
е. как истинное или ложное значение.
Логические операторы языка Perl включают
следующие:
? || логическое ИЛИ
? && логическое И
Perl всегда обрабатывает логические выражения
слева направо. Кро-
ме того. Perl всегда прекращает оценку, если уже
выполненной
оценки достаточно, чтобы определить значение
результата. В допол-
нение к общим логическим операторам Perl
поддерживает следующие
дополнительные логические операторы:
? ! логическое отрицание ()
? ?: условная операция
? , последовательное выполнение
Оператор логического отрицания (!) заменяет
значение булевой ве-
личины на противоположную. Так же как и в С, в
языке Perl услов-
ный оператор (?:) использует три операнда.
Выражение, использую-
щее условный оператор, имеет следующую форму:
Condition ? true-result : false-result
Аналогично, следующее выражение использует
условный оператор для
того, чтобы предоставить Бобу полный доступ, а
всем остальным -
ограниченный:
$access = ($user eq 'Bob' ? 'Full' : 'Limited');
Оператор последовательного выполнения <,>
(также известный как
оператор запятая) не является вполне логическим
оператором, пос-
кольку он не анализирует истинность своих
операндов. Perl выпол-
няет операнды оператора последовательного
выполнения слева напра-
во и возвращает значение самого правого
операнда. Следующий при-
мер иллюстрирует использование оператора
запятая в цикле for.
СТРОКОВЫЕ ОПЕРАТОРЫ
Поскольку Perl представляет собой язык для
обработки текста,
неудивительно, что в него включены
дополнительные операторы для
работы со строками. Ниже перечисляются операторы
обработки строк:
?. конкатенация строк ? х репликация ? =~
сопоставление перемен-
ной с образцом ? !~ то же, что и предыдущее, но с
дополненным от-
рицанием результата
Первые два оператора легко иллюстрируются
примером:
print 'b' . 'an' x 2 . 'a'; # выведет 'banana'
Как показано, это выражение использует
конкатенацию строк и
оператор репли-кации для того, чтобы напечатать
строку <banana>.
Два последних оператора используются для
проверки того, включает
ли строковый операнд заданный образец. Этот
вопрос детально об-
суждается в разделе <Регулярные выражения>.
Следующий пример ил-
люстрирует их использование:
В этом случае оператор проверки вхождения в
строку образца
(=~) использовался для проверки того, входит ли
образец ana в пе-
ременную $var. В данном случае выражение принимает
значение <ис-
тинно>.
ОПЕРАТОРЫ ПРИСВАИВАНИЯ
Если вы знакомы с языком программирования С, то
формы опера-
торов присваивания языка Perl должны быть для вас
совершенно зна-
комыми. Так же как и в С, эти операторы заставляют
Perl выпол-
нить специальные операции со значениями, которые
появились с пра-
вой стороны оператора, и затем выполнить
присваивание:
= += -= *= /= %= |= &=
^= ~= <<= >>= **= .= x=
LVALUES
В языке Perl, так же как и в С, lvalue представляет
собой
имя того, что стоит с левой стороны оператора
присваивания. Та-
ким образом, lvalue представляет собой целостность,
которой мо-
жет быть присвоено значение, например, lvalue может
быть перемен-
ной. Например, скрипт Perl не может присвоить
значение строке
символов, наподобие выражения <Bob> = 32,
поскольку <Bob> не яв-
ляется lvalue. Тем не менее, скрипт может присвоить
значение пе-
ременной $Bob, например, следующим образом $Bob = 32,
поскольку
переменная $Bob является lvalue. В языке Perl любая
целостность,
которая может использоваться как lvalue, обычно
таковой и являет-
ся. Например, следующее выражение упаковывает
(pack) и распаковы-
вает (unpack) список значений, причем список
переменных в первом
случае и три скалярных во втором являются lvalues:
Когда вы работаете со списками в языке Perl,
оператор прис-
ваивания не обяза тельно относится ко всему
списку. Скрипт может
присваивать значения отдельным элементам
списка, как показано ни-
же:
@items[2,4,7] = (100,200,300);
В этом случае оператор присваивает значение трем
элементам
списка. Аналогичным образом следующее выражение
распаковывает
элементы списка, присваивая значения двух первых
элементов двум
скалярным переменным, а остаток массива -
списочной переменной:
($arg1,$arg2,@rest) = @ARGV; # можно смешать скаляры и массивы
ОПЕРАЦИИ ДЛЯ РАБОТЫ СО СПИСКАМИ
В состав операций для работы со списками входят
следующие:
? , конструктор списков
? .. оператор области
? х оператор репликации
Вы уже использовали конструктор списков для
инициализации
массивов и создания списка переменных,
использованных как
lvalues. Оператор области возвращает в качестве
значения последо-
вательность целых чисел, которая начинается от
левого операнда и
продолжается до правого операнда включительно.
Скрипты часто ис-
пользуют оператор области совместно с
конструктором списков для
создания списков. Например, следующее выражение
использует опера-
тор области для того, чтобы создать список под
именем @digits,
который содержит числа от нуля до девяти:
@digits = 0..9; # список (1,2,3,4,5,6,7,8,9)
Аналогичным образом, это выражение может
использовать опера-
тор области для создания области изменений
индексов массива.
Предположим, что список @days содержит дни недели
(начиная с вос-
кресенья). В следующем выражении списку @weekdays
присваиваются
значения, начиная от понедельника до пятницы:
@weekend = @days[1..5];
Наконец, следующее выражение использует два
оператора облас-
ти для создания списка шестнадцатиричных цифр:
@hex_digits = (0..9,a..f);
Оператор репликации просто создает копии
данного операнда
указанное число раз. Например, в следующем
выражении список зна-
чений 1, 2, 3 повторяется три раза:
ОПЕРАТОРЫ ДЛЯ РАБОТЫ С ФАЙЛАМИ
Perl содержит обширный список операторов для
работы с файла-
ми. Имеется не менее 27 операторов, возвращающих
специфическую
информацию о файле, даже не открывая его. Многие
операторы языка
Perl ориентированы на системы UNIX, но следующие
операторы рабо-
тают на любых системах: ? -d проверяет наличие
каталога ? -е оп-
ределяет наличие файла ? -s определяет размер
файла ? -w опреде-
ляет, можно ли писать в данный файл
Следующие два файловых оператора возвращают
булево значение.
Третий оператор возвращает размер файла в
байтах. Следующий текст
иллюстрирует использование этих операторов:
if (-e,'perl.exe')
{
print 'File size is:' -s 'perl.exe';
}
else
{
print 'can\' t find perl.exe\n';
}
(-w 'SomeFile') || die "Cannot write to SomeFile\n";
ПРИОРИТЕТЫ ВЫПОЛНЕНИЯ ОПЕРАТОРОВ
Как и всякий язык программирования, Perl
определяет приори-
теты выполнения операторов, с помощью которых
упорядочивается
последовательность их выполнения. Таблица 12.2
перечисляет прио-
ритеты операторов начиная от высшего и следуя к
низшему:
? ++-
? ! ~ унарный минус
? **
? =~ !~
? * / % х
? +-
? <<>>
? -d -е -s -w (и другие файловые операторы)
? <> <= >= It gt le ge
? = = != < => eq ne cmp
? &
? |^
? &&
? ||
? ..
?
? : = += -= *=
Табл. 12.2. Приоритеты операторов языка Perl от
высшего к низшему
В своем скрипте вы можете изменять
последовательность выпол-
нения операторов с помощью скобок.
КОНСТРУКЦИИ ЯЗЫКА PERL
Perl поддерживает все выражения языка С, используя
почти
идентичный их формат. Например, управляющие
конструкции if,
while, do. for и goto используются в обоих языках в
одинаковой
форме. Как вы увидите в дальнейшем, оператор continue
имеет нес-
колько иное значение в языке Perl. Его прежнее
значение теперь
называют next, а оператор break называют теперь last. Perl
не
реализует оператор switch. Кроме того, некоторые
выражения языка
С можно найти в Perl в иных форматах и добавлены
многие новые вы-
ражения.
ПРОСТЫЕ И СОСТАВНЫЕ ОПЕРАТОРЫ
Простым выражением называется любая допустимая
комбинация
операторов и операндов. В языке Perl оператором
является выраже-
ние, заканчивающееся точкой с запятой. Как и в
языке программиро-
вания С, все операторы оканчиваются точкой с
запятой. Когда вы
вводите текст программы в отладчик, можно
опускать точку с запя-
той, поскольку отладчик поставит ее за вас.
Следующий текст ил-
люстрирует простой оператор присваивания на
языке Perl:
$Title = 'Web Programming';
Так же как и при программировании на С, скрипты Perl
могут
содержать блоки операторов, или составные
операторы, которые по-
мещаются в фигурные скобки ({}), как показано ниже:
{
# Операторы
# Другой блок операторов
}
Ваши скрипты будут широко использовать блоки
инструкций на-
ряду с более сложными операторами. Как и в языке
С, скрипты на
языке Perl могут использовать блоки инструкций для
определения
области видимости (scope) локальных переменных.
Однако определе-
ние локальных переменных в блоке не является
автоматическим. Для
их декларации скрипт должен использовать
ключевое слово local.
Далее в этой главе мы рассмотрим область
видимости переменных в
деталях.
УСЛОВНЫЕ ОПЕРАТОРЫ
Многие предыдущие примеры использовали оператор
if. В языке
Perl оператор if почти что идентичен оператору if в
языке С.
Отличие, однако, состоит в том, что в языке С
оператор if может
использовать простую инструкцию без фигурных
скобок, тогда как в
языке Perl инструкции обязательно должны быть
заключены в фигур-
ные скобки, образуя блок.
if (expr)
statement; // приемлемо для C но не для Perl
if (expr)
{
statement; # вот так нужно делать в Perl
}
Аналогичным образом инструкции языка Perl else
работает нем-
ного отлично от соответствующей инструкции в С. В
языке Perl ин-
струкции также должны быть заключены в фигурные
скобки и образо-
вать блок:
// Пример в С неприемлемо в Perl
if (expr1)
statament1;
else if (expr2)
statement2;
else
ststement3;
Ниже показано, что Perl позволяет использовать
конструкцию
elsif:
ОПЕРАТОР UNLESS
В языке программирования С программисты
используют логичес-
кое отрицание (!) для изменения булевой величины
на противополож-
ное, как показано ниже:
if (!(expr)) // Отрицание на С
{
statement;
}
Наряду с использованием логического отрицания,
скрипты Perl
часто содержат оператор unless, который
обеспечивает то же самое,
что и записанный выше код на С.
unless (expr)
{
statement;
}
Примечание: В отличие от языка С, Perl не содержит
оператора пе-
реключения switch.
ОПЕРАТОР DO
Одним из частных случаев блочных операторов
служит оператор
do, который позволяет блоку инструкций возвращать
значения. Зна-
чением, которое оператор do возвращает, является
значение послед-
него выражения, оцененного в рамках блока.
Например, следующий
оператор do сравнивает строковую переменную $Month с
месяцами го-
да и присваивает переменной $DayCount значение,
равное числу дней
в месяце:
Обратите внимание, что Perl требует наличия точки с
запятой
в конце блока do. Не путайте блок do с оператором do
while, кото-
рый будет рассматриваться ниже в этой главе.