15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


ЯЗЫК ПРОГРАММИРОВАНИЯ PERL

В главе 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), необходимо использовать символ продолжения
<\> конце каждой строки.. Иначе отладчик сообщит о синтаксичес-
кой ошибке.

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

DB<3> for ($i = 0; $i < 10; $i++) { \ <ENTER>
cont: print $i; \ <ENTER>
cont: } <EIITER>
0123456789
DB<4>

В этом случае для вывода чисел от 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 обрабатывает числа
целого типа и с плавающей запятой:

print 6 & 3; # выведет 2
print 6.9 & 3.1 #
print 7 / 2 # выведет 2.3333 не целое
print int(7/3) # выведет 2

Точно так же, как Perl преобразует числа с плавающей запя-
той в целые числа: когда скрипт использует целочисленные значе-
ния, он также преобразует числа в строки и наоборот, когда такое
преобразование имеет смысл. Например, если скрипт использует чис-
ла в контексте, где только строки имеют смысл, например, при сое-
динении строк, он конвертирует числа в строки. Аналогичным обра-
зом, если требуется использовать строки там, где только числа
имеют смысл, то Perl конвертирует их в числа. Работая со скрипта-
ми Perl, обычно не надо беспокоиться о внутреннем представлении
скалярных величин. Perl поддерживает также концепцию булевых зна-
чений, но не имеет для их описания специального типа. Как и в С,
численное значение рассматривается истинным, если оно не равно
нулю. Дополнительно строковое значение рассматривается как истин-
ное, если оно не равно '' или '0'. Некоторые булевы операторы,
такие как <>> (больше), возвращают единицу в качестве значения
<истинно> и нуль - в качестве <ложно>. Тем самым, ваш скрипт дол-
жен просто рассматривать ненулевые величины как строчного типа,
так и числового в качестве булева значения <истинно>. Скрипты
Perl могут группировать скалярные величины вместе и создавать
список (list). Если скрипт хранит список в какой-то переменной,
то эта переменная становится массивом (array).

ПЕРЕМЕННЫЕ
Perl поддерживает три типа переменных: скаляры, массивы и
ассоциативные массивы. Как и в языке С, имена переменных пишутся
с различением строчных и заглавных букв. Таким образом, имена
VAR, Var и var описывают различные переменные. Скрипт может иметь
скалярную переменную под именем var и переменную-массив, также
названную var. Они будут различаться в языке Perl в соответствии
с контекстом.


Примечание: Переменные Perl нетипизированы, как это делается и в
С. Например, скалярная переменная может содержать любой тип ска-
ляра, и приведение типов осуществляется автоматически. Также, как
вы могли уже заметить, переменные на языке Perl необязательно
должны быть объявлены. Если переменная не объявлена, то Perl рас-
сматривает ее как глобальную. Ниже вы познакомитесь с объявле-
нием переменных и их областью видимости.

СКАЛЯРНЫЕ ПЕРЕМЕННЫЕ
Как отмечалось, скалярная переменная может содержать един-
ственное значение. В языке Perl имена скалярных переменных всег-
да начинаются со знака ($). В еле дующем выражении скалярной пе-
ременной $age присваивается значение 35, а переменной $name -
строковое значение <Bob>. Затем используется функция print для
вывода значения каждой из переменных:

$age = 35;
$name = 'Bob';
print ($name,'is',$age);

Если вы сохраните эти выражения в файле под именем
SCALAR.PL, то сможете запустить программу следующим образом:

C:\PERL> Perl SCALAR.PL <ENTER>
Bob is 35

МАССИВЫ
Как было сказано выше, массивы представляют собой перемен-
ные, принимающие в качестве значения список из скалярных величин.
Следующий текст программы на языке Perl иллюстрирует объявление
переменных типа массив и их инициализацию:


@days = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');

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 = ($age, $name)
@FriendsOfMine = ('Joe','Mary', @FriendsOfYours);

В следующем примере используются части массивов:

@weekend = @days[0,6] ; # результат ('Sun','Sat')
print (@days[1..5,0,6]); # выведет 'MonTueWedThuFriSunSat'

Если скрипт использует переменную типа массив в контексте
скаляра, то значением служит число элементов массива. Скалярным
контекстом является такой контекст, где только скалярные значе-
ния имеют смысл. Например, следующее выражение использует скаляр-
ный контекст для массива stuff для того, чтобы определить число
элементов содержащееся в массив. Если число элементов, больше или
равно 2, то скрипт выдает сообщение и заканчивает исполнение:

(@stuff >= 2) || die "Too much stuff! \n";

Функция die служит директивой языку Perl закончить выполне-
ние и выдать при этом указанное сообщение. Если сообщение не со-
держится, то функция просто заканчивает выполнение скрипта. Perl
также поддерживает специальную конструкцию $# переменная, кото-
рая возвращает последнее значение индекса в массиве. Например,
следующее выражение for использует $[ для того, чтобы определить
начальное значение индекса массива, и $# для определения послед-
него из элементов массива. При этом с помощью выражения for выво-
дятся значения каждого из элементов:

for ($i =$[; $i <= $#stuff; $i++)
{
print $stuff[$i];
}

Записанный цикл 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;

АССОЦИАТИВНЫЕ МАССИВЫ
Ассоциативные массивы аналогичны обычным массивам в том от-
ношении, что они представляют собой список скалярных переменных.
Различие заключается в том, что массив должен использовать цело-
численные значения в качестве индексов при выборе элементов мас-
сива, тогда как ассоциативный массив может использовать величины
любого типа для выбора элементов массива. Индексные величины для
ассоциативного массива называются ключами. Рассмотрим следующие
примеры:

$ages{'Bob'} = 35;
$ages{'Mary'} = 25;
$, = ' '; # change output separator for print operator

print @ages{'Bob','Mary'}; # выведет '25 35'
print keys(%ages); # выведет 'Bob Mary'

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:

$x = 2.5;
$y = 3;
print ($x + 2*$y); # выведет 8.5
print (7 / $y); # выведет 2.3333333
print int (7 / $y); # выведет 2
print (7 % $y); # выведет 1
print (7.5 % $y); # выведет 1


Примечание: В языке 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: ? | побитовое ИЛИ ? & побитовое И ? ^ побитовое исключаю-
щее ИЛИ ? ~ побитовая инверсия ? << сдвиг влево ? >> сдвиг вправо

Рассмотрим следующие примеры побитовых операций:
$x = 5; # 101 в двоичном
$y = 3; # 011 в двоичном
print $x | $y; # 7 (111)
print $x & $y; # 1 (001)
print $x ^ $y # 6 (110)
print $x & ~1; # 4 (100)
print $x << 2 # 20 (10100)
print $x >> 1 # 2 (10)

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

ОПЕРАТОРЫ СРАВНЕНИЯ
Операторы сравнения сравнивают величины двух операндов. Так
же как при работе с арифметическими операторами, 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.

For ($i=0, $j=10; $i<10; $i++, $j-)
{
print i$,' ',$j
}


СТРОКОВЫЕ ОПЕРАТОРЫ
Поскольку Perl представляет собой язык для обработки текста,
неудивительно, что в него включены дополнительные операторы для
работы со строками. Ниже перечисляются операторы обработки строк:
?. конкатенация строк ? х репликация ? =~ сопоставление перемен-
ной с образцом ? !~ то же, что и предыдущее, но с дополненным от-
рицанием результата

Первые два оператора легко иллюстрируются примером:

print 'b' . 'an' x 2 . 'a'; # выведет 'banana'

Как показано, это выражение использует конкатенацию строк и
оператор репли-кации для того, чтобы напечатать строку <banana>.
Два последних оператора используются для проверки того, включает
ли строковый операнд заданный образец. Этот вопрос детально об-
суждается в разделе <Регулярные выражения>. Следующий пример ил-
люстрирует их использование:

$var = 'banana';
print ($var =~ /ana/) ? TRUE : FALSE;

В этом случае оператор проверки вхождения в строку образца
(=~) использовался для проверки того, входит ли образец 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:

@color = ($r, $g, $b); # пакет цветов
($r, $g, $b) = @color; # распаковка цвета

Когда вы работаете со списками в языке 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:

if (expr1)
{
statament1;
}
elsif (expr2)
{
statement2;
}
else
{
ststement3;
}

ОПЕРАТОР UNLESS
В языке программирования С программисты используют логичес-
кое отрицание (!) для изменения булевой величины на противополож-
ное, как показано ниже:

if (!(expr)) // Отрицание на С
{
statement;
}

Наряду с использованием логического отрицания, скрипты Perl
часто содержат оператор unless, который обеспечивает то же самое,
что и записанный выше код на С.

unless (expr)
{
statement;
}

Примечание: В отличие от языка С, Perl не содержит оператора пе-
реключения switch.

ОПЕРАТОР DO
Одним из частных случаев блочных операторов служит оператор
do, который позволяет блоку инструкций возвращать значения. Зна-
чением, которое оператор do возвращает, является значение послед-
него выражения, оцененного в рамках блока. Например, следующий
оператор do сравнивает строковую переменную $Month с месяцами го-
да и присваивает переменной $DayCount значение, равное числу дней
в месяце:

$DayCount = do
{
if ($Month eq 'September' || $Month eq 'April' || $Month eq 'June' ||
$Month eq 'November')
{
30;
}
elsif ($Month eq 'Februry')
{
$Year & 3 ? 28 : 29; # Проверка на весокосный год
}
else
{
31;
}
};

Обратите внимание, что Perl требует наличия точки с запятой
в конце блока do. Не путайте блок do с оператором do while, кото-
рый будет рассматриваться ниже в этой главе.

Далее