Perl программа (скрипт) состоит из последовательности деклараций и предложений. Единственно что должно быть обязательно декларировано, это форматы отчетов и подпрограммы (функции). Все необъявленные переменные, массивы имеют значение 0 или null.
Perl имеет свободный формат.
Комментарии начинаются с символа '#'
и продолжаются до конца строки.
Декларации могут использоваться в
любом месте программы так же как и
предложения (statements), но действуют
они только в фазе компиляции
программы. Обычно их помещают или в
начале или в конце программы.
Декларация подпрограмм позволяет
использовать имя подпрограммы как
списковый оператор, начиная с
момента декларирования.
Пример:
sub test; # Декларация подпрограммы test $var1 = test $0; # Использование как оператора списка.
Декларации подпрограмм могут быть загружены из отдельного файла предложением require или загружены и импортированы в текущую область имен предложением use. Подробно см. главу Модули.
Простое предложение обязательно заканчивается символом ';' если только это не последнее предложение в блоке где ';' можно опустить. Заметьте, что существуют операторы такие как eval{} и do{}, которые выглядят как сложные предложения, но на самом деле это термы и требуют обязательного указания конца предложения.
Любое простое предложение может содержать single модификатор перед ';'. Существуют следующие single модификаторы:
if EXPR unless EXPR while EXPR until EXPR
где EXPR - выражение, возвращающее логическое значение true или false. Модификаторы while и until вычисляются в начале предложения кроме блока do, который выполняется первым.
if EXPR- Модификатор "если". Предложение выполняется, если EXPR возвращает true.
Пример:
$var = 1; $var2 = 3 if $var > 0; # Результат: $var2 = 3
while EXPR - Модификатор "пока". Предложение выполняется пока EXPR = true
Пример:
$var = 1; print $var++ while $var < 5; # Печать $var с инкрементом
Результат: 1234
until EXPR- Модификатор "до ". Предложение выполняется до тех пор пока EXPR = false
Пример:
$var = 1; print $var++ until $var > 5; # Печать $var с инкрементом
Результат: 12345
unless EXPR - Модификатор "если не" . Обратный к if. Выражение выполняется если EXPR = false.
Пример:
$var = 1; print $var++ unless $var > 5; # Печать $var с инкрементом
Результат: 1
Последовательность простых предложений, ограниченная функциональными ограничителями, называется блоком. В Perl это может быть целый файл, последовательность предложений в операторе eval{} или чаще всего это множество простых предложений, ограниченных круглыми скобками '{}'.
Существуют следующие виды сложных предложений:
LABEL while (EXPR) BLOCK
LABEL while (EXPR) BLOCK continue BLOCK
LABEL for (EXPR; EXPR; EXPR) BLOCK
LABEL foreach VAR (LIST) BLOCK
LABEL BLOCK continue BLOCK
Обратите внимание, что сложные предложения описаны в термах блоков, а не предложений, как в языках C или Pascal. Поэтому необходимо всегда использовать круглые скобки для обозначения блока.
if (EXPR) BLOCK -
Вычисляется логическое выражение
EXPR и если true блок выполняется.
Пример:
$var =1; if ($var == 1) { print $var,"\n"; }
Результат: 1
if (EXPR) BLOCK else BLOCK2 - Если
EXPR=true выполняется BLOCK иначе BLOCK2.
Пример:
$var =2; if ($var == 1) { print "\$var = 1\n"; } else { print "\$var не равно 1\n"; }
Результат: $var не равно 1
if (EXPR1) BLOCK1 elsif (EXPR2) BLOCK2 ...
else BLOCK - Если EXPR1=true выполняется
BLOCK1 иначе если EXPR2=true выполняется
BLOCK2 иначе ... иначе BLOCK.
Пример:
$var = 1; if ($var == 0) { print "\$var = 0\n"; } elsif ($var == 1) { print "\$var = 1\n"; } else { print "Не известное \$var\n"; }
Результат: $var = 1
Цикл while выполняет BLOCK до тех пор пока EXPR = true. Метка LABEL не обязательна и состоит из идентификатора, завершающегося символом ':'. Метка необходима при использовании внутри блока цикла управляющих операторов next, last и redo. Если метка все же отсутствует, то эти операторы ссылаются к началу ближайшего цикла. Блок после continue выполняется всегда перед тем как вычисляется логическое выражение EXPR. Это подобно EXPR3 в предложении for, поэтому в этом блоке удобно изменять счетчики и флаги цикла даже если применяется оператор next.
next - подобен continue в С. Переходит к началу текущего цикла т.е. повторяет итерацию.
Пример:
M1: while ($i < 6) { ++$i; # Увеличиваем счетчик на 1 next M1 if $i < 3; # Переходим в начало если $i < 3 ++$i; # иначе увеличиваем счетчик еще раз на 1 } continue { print "$i "; # Печатаем $i }
Результат: 1 2 4 6
last - подобен оператору break в языке С. Немедленно прерывает цикл. Блок continue пропускается.
Пример:
M1: while ($i < 6) { ++$i; # Увеличиваем счетчик на 1 last M1 if $i > 3; # Выход из цикла если $i > 3 ++$i; # иначе увеличиваем счетчик еще раз на 1 } continue { print "$i "; # Печатаем $i }
Результат: 2 4
redo - начать новый цикл не вычисляя EXPR и не выполняя continue блок.
Пример:
M1: while ($i < 6) { ++$i; # Увеличиваем счетчик на 1 redo M1 if $i == 3; # Далее пропустить для $i = 3 ++$i; # иначе увеличиваем счетчик еще раз на 1 } continue { print "$i "; # Печатаем $i }
Результат: 2 5 7
LABEL for (EXPR1; EXPR2; EXPR3) BLOCK
Оператор for полностью аналогичен
оператору for в С. В перед началом
цикла выполняется EXPR1, если EXPR2 = true
выполняется блок, затем
выполняется EXPR3.
Пример:
for ($i = 2; $i < 5; ++$i) { print $i, " "; } print "\nПосле цикла i = $i\n";
Результат:
LABEL foreach VAR (LIST) BLOCK
Переменной VAR присваивается
поочередно каждый элемент списка
LIST и выполняется блок. Если VAR
опущено, то элементы присваиваются
встроенной переменной $_. Если в
теле блока изменять значение VAR то
это вызовет изменение и элементов
списка т.к. VAR фактически указывает
на текущий элемент списка. Вместо
слова foreach можно писать просто for -
это слова синонимы.
Пример:
@месяц = ("январь","февраль","март"); # Создали массив foreach $i (@месяц) { print $i," "; # Печать $i }
Результат: январь февраль март
Пример:
@месяц = ("январь","февраль","март"); # Создали массив foreach $i (@месяц) { $i = uc($i); # Перевели в верхний регистр } print @месяц;
Результат: ЯНВАРЬФЕВРАЛЬМАРТ
Пример:
for $i (3,5,7) { print "$i "; }
Результат: 3 5 7
Блок не зависимо от того имеет он метку или нет семантически представляет собой цикл который выполняется один раз. Поэтому действие операторов цикла next, last, redo - аналогично описанному выше. Блоки удобны для построения switch (переключатель) структур. В Perl нет специального оператора switch подобного языку С поэтому вы сами можете создавать удобные для вас конструкции. Опыт автора показывает что для простоты написания лучше всего подходит конструкция вида if ... elsif ... else ... хотя можно сочинить и нечто подобное:
SWITCH: { if ($i ==1 ) { .....; last SWITCH; } if ($i ==2 ) { .....; last SWITCH; } if ($i ==3 ) { .....; last SWITCH; } $default = 13; }
Выбирайте сами по своему вкусу.
В Perl существует оператор goto хотя где , как и когда его применять как говорил Ходжа Насреддин "Тонкий философский вопрос". Для начинающих программистов которым от так "нужен" я бы вообще посоветовал "забыть" о его существовании. Однако при создании больших производственных задач на последнем этапе особенно при отработке "отвальных" ошибочных ситуаций конечно goto нужен.
В Perl реализовано три формы goto. goto - метка, goto - выражение и goto - подпрограмма.
goto | метка выполняет непосредственный переход на указанную метку. |
---|---|
goto - выражение | Вычисляет имя метки и
делает соответствующий
переход. Например если мы хотим
сделать переход на одну из трех
меток "M1:", "M2:" или
"M3:" в зависимости от
значений переменной $i равной 0,
1 или 2 то это лучше сделать
следующим образом: goto ("M1", "M2", "M3")[$i]; здесь $i используется как индекс массива указанного непосредственно в выражении. |
goto подпрограмма | довольно редкий случай т.к. всегда проще и надежней вызвать подпрограмму "естественным" образом. |
POD операторы. Документирование программ.
В Perl реализован очень удобный механизм для написания документации в момент создания программы. Для этого применяются специальные POD операторы. Если в теле программы интерпретатор встречает оператор начинающийся с символа '=' например:
= head Набор стандартных процедур
то пропускается все до слова '=cut'. Это удобно для включения длинных на несколько строк или страниц комментариев. Затем с помощью специальной программы pod можно отделить текст документации от текста программы.
[Назад] [Содержание] [Вперед]