Поиск

БЛОКИ

Простейшим способом объединения нескольких операторов Perl является блок. Для образования блока достаточно заключить группу операторов в фигурные скобки:

{
оператор_а;
оператор_b;
оператор_в;

}

Внутри блока операторы выполняются последовательно, как и раньше. Блоки могут состоять из других блоков, например:

{
оператор_а;
{
оператор_b;
оператор_в;

}
}

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

{ оператор; { другой_оператор; }
{ последний_оператор; } }

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

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

Оператор if

Для управления условным выполнением операторов Perl обычно используется оператор if. Синтаксис этого оператора приведен ниже:

if (выражение)БЛОК

Работает оператор if так: если выражение истинно, блок кода выполняется. Если выражение ложно, блок кода не выполняется. Рассмотрим пример:

if < $r == 5 ) { print 'Переменная $r равна 5.';
}

В этом примере проверяется значение переменной $r на равенство 5. (Символы == — это оператор равенства; не путайте его с оператором присваивания =.) Если операнды с обеих сторон этого оператора (в нашем случае $r и 5) численно равны, выражение считается истинным и выполняется оператор print. Если значение $r не равно 5, оператор print не выполняется.

Оператор if позволяет также выполнить один фрагмент кода, если некоторое условие истинно, и другой фрагмент кода — если это условие ложно. Это достигается с помощью использования оператора if-else. Его синтаксис имеет вид

if (выражение) | Если выражение истинно...
БЛОК | выполняется этот блок кода
Else
БЛОК | В противном случае выполняется этот блок.

Блок, следующий за выражением, выполняется, если оно истинно, а блок после ключевого слова else — если выражение ложно. Приведем пример использования описываемого оператора:

$r=<STDIN>; chomp $r;
if ($r == 10) {
print '$r равно 10 ';
} else {
print '$r не равно 10 . . . ' ;
$r=10;
print '$r присвоено значение 10 ';
}
Обратите внимание, что в предыдущем примере для присваивания значения переменной $r используется оператор =. Для проверки значения $r используется оператор равенства ==. Это два совершенно разных оператора с абсолютно различным действием. Не путайте их, иначе отладка ваших программ может сильно усложниться. Помните, что с помощью оператора = значения присваиваются переменным, а с помощью оператора == — выражение проверяется на равенство определенному значению.

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

if (выражение1) | Если выражение 1 истинно...
БЛОК1 | ..выполняется этот блок кода.
elseif (выражевие2) | Иначе, если выражение2 истинно...
БЛОК2 | выполняется этот блок кода
else
БЛОКЗ | Если нн одно из выражений не истинно, выполняется этот блок.

Данный оператор выполняется следующим образом: если выражение, помеченное как выражение1, истинно — выполняется блок кода БЛОК1. Иначе управление передается оператору elseif и проверяется значение выражения2. Если ни выражение1, ни выражение2 не являются истинными, выполняется БЛОКЗ. Для демонстрации такой синтаксической конструкции рассмотрим реальный фрагмент программы на Perl:

$r=10;
if ($r== 10) {
print ' $r равно 10 ! ' ;
} elseif ($r ==20) {
print ' $r равно 20! ' ;
} else {
print ' $r не равно ни 10, ни 20 ' ;
Другие операторы отношения

До сих пор мы сравнивали значения лишь с помощью оператора равенства ==. В Perl имеется еше ряд операторов, предназначенных для сравнения численных значений, большинство из них представлены в табл. 3.1.

Эти операторы могут использоваться в любом месте программы для сравнения численных значений, например в операторе if, как показано в листинге 3.1.

Проведем анализ программы.

  • Строка 1. Это стандартная первая строка программ на Perl. В ней указывается Полный путь к программе-интерпретатору, а ключ -w активизирует режим выдачи предупреждений. На 1-м занятии, "Начало работы с Perl", мы говорили о " том, что в каждом конкретном случае эта строка может несколько видоизменяться.
  • Строка 3. Функция rand 10 генерирует случайное число в диапазоне от 0 до 10, а оператор int() возвращает его целую часть. Затем получившееся целое число от 0 до 9 присваивается переменной $im_thinking_of.
  • Строки 4—6. В этом месте программы у пользователя запрашивается значение, которое присваивается переменной $guess. С помощью функции chomp завершающий символ перевода строки удаляется.
  • Строки 8—9. Если значение переменной $guess больше, чем переменной $im_thinking of, выводится соответствующее сообщение.
  • Строки 10—11. Если же значение переменной $guess меньше, чем переменной $im_thinking of, выводится другое сообщение.
  • Строки 12~13. Оставшийся вариант — пользователь угадал число.

Операторы в табл. 3.1 используются для сравнения лишь численных значений. Их использование для сравнения нечисловых данных приводит к неожиданному результату. Рассмотрим пример:

$first="Simon";
$
last*"simple";
if ($first == $last) { t == - совсем не то, что вы ожидали!
Print "Значения переменных равны !n";
}

В результате выполнения этого фрагмента кода окажется, что значения переменных $ first и $last численно равны. На 1-м занятии, "Начало работы с Perl", говорилось, что если нечисловые строки используются там, где Perl ожидает встретить число, то вместо них подставляется нулевое значение. Поэтому предшествующее выражение оператора if в Perl равносильно следующему: if { 0 == 0 ). Это выражение истинно, и результат действия оператора if совсем не такой, как вы, вероятно, ожидали.

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

Для сравнения нечисловых значений используйте другие операторы Perl, приведенные в табл. 3.2.

Данные операторы выполняют анализ текстовых строк на основе сравнения ASCII-кодов соответствующих символов, начиная с первого. Это означает, что строки, расположенные первыми в алфавитном порядке, имеют высший приоритет. Таким образом, наибольший приоритет имеют знаки пунктуации, затем числа, прописные буквы и, наконец, строчные буквы. Например, строка 1506 больше строки Happy, а та, в свою очередь, больше строки happy.

Что есть Истина в Perl

До сих пор мы свободно пользовались термином истины: "если это выражение истинно...", не имея его формального определения. В Perl есть несколько коротких правил относительно того, что истинно, а что ложно. Правила эти таковы:

  • число 0 имеет значение Ложь;
  • пустая строка ("") или строка "0" имеет значение Ложь;
  • неопределенные значения undef имеют значение Ложь;
  • все остальные значения считаются истинными.

Логично, не правда ли? Единственно, о чем еще следует помнить — перед тем, как проверить на истинность некоторое выражение, его необходимо упростить: определить значения вызываемых функций и арифметических выражений. Затем полученное значение выражения нужно перевести в скалярный вид и только тогда решить, истинно оно или ложно.

Постарайтесь осмыслить эти правила и посмотрите табл. 3.3. Попробуйте сначала сами определить, какое выражение истинно, а какое ложно.

Пока в операторе if мы использовали только операторы отношения, хотя, в принципе, можно использовать любое выражение, которое в конечном счете будет приводиться к значению Истина или Ложь.

| Анализируется значение скалярной переменной $а и определяется его логическое значение
if ($a) { ... }
| Вычисляется длина переменной $Ь. Если она ненулевая, логическое значение выражения - Истина.
If (length (Sb)) { .... }

В Perl имеется специальное значение — undef. Оно присваивается всем неинициализированным переменным. Кроме того, некоторые функции в случае неудачного исхода их выполнения возвращают это значение. Значение undef трактуется интерпретатором Perl как неопределенное. Оно не равно нулю или любому значению в привычном понимании этого слова. При проверке на истинность, например в операторе if, undef всегда имеет логическое значение Ложь. В арифметических выражениях вместо undef всегда подставляется 0.

Использование неинициализированных переменных обычно свидетельствует об ошибке в программе. Если в программе на Perl с включенным режимом вывода предупреждений значение undef используется в выражениях или передается в виде аргумента функциям — появляется сообщение Use of uninitialized value.
Логические операторы

Допустим, вам требуется написать код, выполняющий что-либо, если переменные $х и $у имеют истинное значение, a $z — ложное. Такой код можно реализовать с помощью плохо читаемого набора операторов if:

if ($х) {
if ($У) {
if ($z) {
| Ничего не происходит
} else {
print "Нужное условие достигнуто. n
}
}
}

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

Предыдущий пример можно переписать с дующим образом:

if ($x and $y and not $z) {
print "Нужное условие достигнуто. n";
}

Выражения, объединенные логическими операторами, вычисляются слева направо до тех пор, пока не появится возможность заранее определить значение всего логического выражения (листинг 3.2).

Проведем анализ программы.

  • Строка 1. В этой строке переменным присваиваются значения.
  • Строка 3. Вначале определяется логическое значение переменной $а. Поскольку оно ложно, выражение с использованием оператора and никогда не может быть истинно. Поэтому логическое значение переменной $Ъ не определяется — в этом нет необходимости, ведь уже известно, что выражение ложно. В результате оператор print не выполняется.
  • Строка 4. Вначале определяется логическое значение переменной $d. Оно ложно, но все выражение с оператором or все еще может быть истинным, поэтому вычисляется логическое значение переменной $Ь, оно истинно, значит, и все выражение истинно, следовательно, оператор print выполняется.
  • Строка 5. Вначале определяется логическое значение переменной $d. Оно ложно, но, несмотря на это все, выражение может быть истинным по той же причине, что и в строке 4, — в нем содержится логический оператор or. Значение переменной $b истинно, следовательно выражение not $b — ложно. Истинность или ложность всего выражения еще не установлена, осталось проверить значение переменной $с. Эта переменная имеет истинное значение, следовательно, и все выражение истинно, и оператор print выполняется.

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

$message='Переменные $а и истинны.';
($а and $b) or $message="Одна или обе переменные $а или $Ь ложны.";

В предыдущем примере, если одна из переменных $а или $Ь имеет значение Ложь, будет вычисляться правая часть оператора or, и значение переменной $message модифицировано. Если же обе переменные истинны, значение выражения or также будет истинно, поэтому правая часть оператора or не выполняется. В результате значение переменной Smessage не меняется. В этом примере использован побочный эффект короткозамкнутости операторов or и and для изменения значения переменной $message.

Строго говоря, операторы || и or не эквивалентны. Отличие состоит в том, что оператор || имеет более высокий приоритет, чем or. Это означает, что при прочих равных условиях в выражениях в первую очередь будут выполняться операторы ||, аналогично тому, как в арифметических выражениях операции умножения выполняются перед операциями сложения. Данное замечание относится и к парам &&/and, и !/not. Однако для большей надежности используйте скобки, гарантирующие требуемый порядок вычисления выражения.

Интересно то, что логические операторы Perl не просто возвращают значение Истина или Ложь. Они возвращают последнее вычисленное значение. Например, выражение 5 &ь 7 возвращает значение 7 (оно является истинным), поскольку в данном случае оно было вычислено последним. Такое свойство логических выражений позволяет использовать приведенные ниже конструкции.

Переменной $nev присваивается старое значение, в случае истинности значения переменной $old, в противном случае присваивается строка "default".

$new=$old || "default";

Это выражение выглядит намного изящнее, чем следующее:

$new=$old;
if {!$old) { | Если значение $old не определено или ложно?
$
new="default";
}