Глава 6.3. Выражения и операцииВыражения в PERLе, как и в других языках программирования, представляют собой комбинации переменных, констант и операций, дающие осмысленный результат. Этот результат может быть скаляром, массивом или ассоциативным массивом. Все операции PERLа подразделяются на:
Операции ввода-вывода описаны в п. 6.2.11, операции с регулярными выражениями в п. 6.4.6. 6.3.1. Операции сравненияОперации сравнения сравнивают два операнда и возвращают 1 или 0 в зависимости от
результата этого сравнения. PERL содержит два набора операций сравнения: для сравнения чисел и для
сравнения строк. Операции первой группы сначала преобразуют операнды в числа, а затем их сравнивают.
Операции второй группы преобразуют операнды в строки и сравнивают их в лексикографическом порядке.
Если задана директива
Следующий пример $a = 299; $b = 30; if ($a < $b) { print "Число $a меньше числа $b\n"; } if ($a lt $b) { print "Строка $a меньше строки $b\n"; } выведет сообщение: Строка 299 меньше строки 30. 6.3.2. Логические операцииPERL содержит два набора логических операций, которые идентичны по своему результату, но имеют разный приоритет. Обратите внимание на то, что результаты операций AND и OR отличаются от принятых в других языках программирования.
Операции and, or, xor и not имеют самый низкий приоритет среди всех операций PERLа. Это позволяет использовать их в правой части операторов без дополнительных круглых скобок, например: open HANDLE, "file.dat" or die "Error: $!\n"; Использование операции || в этом примере потребует скобок: open(HANDLE, "file.dat") || die "Error: $!\n"; 6.3.3. Битовые операцииБитовые операции применяются к операндам, представленным как двоичные числа (т. е. как цепочки битов), и возвращают значение, означающее результат операции.
Операции сдвига применимы только к числовым операндам, но остальные битовые операции применимы и к числам, и к строкам. Если одним из операндов битовой операции является число, то оба операнда преобразуются в целые числа. Если же оба операнда строки, то они преобразуются в строки одинаковой длины и операция выполняется над каждым битом полученных строк. Это позволяет нам применять битовые операции к операндам любой длины. При этом операции | и ^ дополняют более короткую строку справа нулевыми битами, а операция & обрезает более длинную строку до размера более короткой. Мы можем явно указать тип операции, используя кавычки для строк или 0+ для чисел. Примеры: print 1.9 | 2; # 3 (плавающий операнд урезан до целого) print 150 | '105'; # 255 (0x96 | 0x69 равно 0xFF) print '150' | '105'; # '155' (в ASCII) $a = 150; $b = '105'; print 0+$a | 0+$b; # числовые операнды print "$a" | "$b"; # строковые операнды На выполнение битовых операций влияют директивы управления арифметикой. По умолчанию, целые числа
считаются беззнаковыми, поэтому операция правого сдвига заполняет старшие биты результата нулями, а операция ~0
возвращает наибольшее положительное целое число. Директива 6.3.4. Унарные операции6.3.4.1. Унарный плюсУнарный плюс (+) возвращает свой операнд. Единственное осмысленное применение этой операции состоит в том, чтобы отделять имя функции от ее аргументов в скобках. Рассмотрим такой пример: print (10 + 20) / 10; Вопреки ожиданиям, этот оператор печатает не число 3, а число 30. Дело в том, что круглые скобки вокруг аргументов
функции имеют в PERLе наивысший приоритет, т. е. операция print +(10 + 20) / 10; 6.3.4.2. Унарный минусУнарный минус (-) изменяет знак числового операнда на противоположный. Если же операнд является строкой, то возвращается следующий результат:
В частности, конструкции -слово и "-слово" эквивалентны. 6.3.4.3. Создание ссылкиОперация \ возвращает ссылку на операнд. Подробно она рассмотрена в п. 6.2.8. 6.3.4.4. Инкремент и декрементОперации ++ и -- называются соответственно операциями инкремента и декремента. Инкремент увеличивает значение числовой переменной на 1. Если она используется как префикс (++a), то возвращает значение операнда после увеличения его на 1. Если же она используется как постфикс (a++), то возвращает значение операнда перед увеличением его на 1. Если операнд инкремента является строковой переменной, соответствующей образцу /^[a-zA-Z]*[0-9]*$/, то выполняется посимвольный инкремент строки с переносом. Примеры: print ++($x = '99'); # '100' print ++($x = 'a0'); # 'a1' print ++($x = 'Az'); # 'Ba' print ++($x = 'zz'); # 'aaa' Декремент применяется только к числовым переменным и уменьшает значение переменной на 1. Если эта операция используется как префикс (--a), то она возвращает значение операнда после уменьшения его на 1. Если она используется как постфикс (a--), то возвращает значение операнда перед уменьшением его на 1. Примеры: print --($x = 99); # 98 print (($x = 99)--); # 99 print --($x = 'a0'); # -1 6.3.4.5. Именованные унарные операцииPERL содержит множество именованных унарных операций, которые рассматриваются как функции с одним аргументом,
заключенным в необязательные круглые скобки. Например, выражение 6.3.5. Аддитивные операцииСуществуют две аддитивные операции над числами (сложение и вычитание) и одна над строками (конкатенация).
Примеры: print '1' + '2'; # 3 print '1' . '2'; # '12' 6.3.6. Мультипликативные операцииСуществуют четыре мультипликативные операции над числами (умножение, деление, остаток по модулю и возведение в степень) и одна над строками (повторение).
Примеры: print '-' x 80; # печатает строку минусов @ones = (1) x 5; # @ones = (1, 1, 1, 1, 1) @ones = (2) x @ones; # @ones = (2, 2, 2, 2, 2) 6.3.7. Операции присваиванияОперации присваивания присваивают левому операнду результат операции, который определяется
правым операндом и самой операцией. Базовая операция присваивания имеет вид
Операция присваивания возвращает свой левый операнд и потому может использоваться в левой части следующей операции присваивания. Например ($a += 2) *= 3; эквивалентно $a += 2; $a *= 3; Присваивание списка списку возвращает список переменных, которым присвоены значения. Присваивание списка скаляру возвращает количество элементов в этом списке. 6.3.8. q-операцииВ большинстве языков программирования кавычки служат для образования строковых констант. Однако, в PERLе они являются операциями, обеспечивающими интерполяцию строк и сопоставление с образцом. Такие операции мы будем называть q-операциями (от английского слова quote, т. е. кавычка). PERL содержит два набора q-операций, перечисленных в следующей таблице.
Здесь вместо скобок () можно использовать любой символ, не являющийся буквой, цифрой или пробелом, либо парные ограничители: (), [], {}, <>. Примеры использования q-конструкций для создания строковых констант были приведены в п. 6.2.3.2; об их использовании в регулярных выражениях см. п. 6.4.6. 6.3.9. Прочие операции6.3.9.1. РазадресацияОперация разадресации имеет вид: a -> b Она обеспечивает доступ к содержимому ссылок и подробно рассмотрена в п. 6.2.8. 6.3.9.2. Операции связыванияБольшинство операций над регулярными выражениями работают со специальной переменной $_. Для сопоставления с образцом произвольных строк используются операции связывания, которые имеют вид: a =~ b a !~ b где a любое строковое выражение, а b образец для сопоставления, подстановки или транслитерации. Операция =~ возвращает истину, если сопоставление, подстановка или транслитерация прошли успешно, и ложь в противном случае. Операция !~ возвращает логическое отрицание результата =~. Примеры использования этих операций см. в п. 6.4.6. 6.3.9.3. Задание диапазонаОперация задания диапазона имеет вид: a .. b На самом деле это две разные операции в зависимости от контекста. В контексте списка эта операция возвращает список значений (a a+1 b). Для строк диапазон формируется с использованием инкремента, например: foreach (1..10) { # выполняет цикл 10 раз } @a = @a[$#a-4 .. $#a]; # вырезает последние пять элементов @a = ('abc'..'abe'); # @a = ('abc', 'abd', 'abe') В скалярном контексте эта операция ведет себя как триггер, имеющий два состояния и возвращающий истину или ложь. Каждая из операций .. хранит свое собственное состояние. Она ложна, пока ложен ее левый операнд. Как только левый операнд стал истинным, эта операция истинна, пока ложен правый операнд. После того, как правый операнд становится истинным, эта операция вновь возвращает ложь. Результат не становится ложным до следующего обращения к этой операции. Операция .. может проверить правый операнд и стать ложной при том же ее вычислении, когда она стала истинной, но один раз она вернет истину. Если мы хотим, чтобы она не вычисляла правый операнд до следующего обращения к ней, то должны использовать форму a ... b В остальном операции .. и ... идентичны. Правый операнд не оценивается, пока операция находится в состоянии "ложь", а левый операнд не оценивается, пока операция находится в состоянии "истина". Значение, возвращаемое данной операцией, это пустая строка в ложном состоянии, и последовательные целые числа, начиная с 1, в истинном состоянии. Последовательный номер сбрасывается для нового диапазона. К последнему номеру диапазона добавляется строка "E0". Если какой-либо из операндов является константой, то он неявно сравнивается со специальной переменной $. (содержащей номер текущей строки текущего файла). Следующий пример открывает заданный файл и печатает его строки с первой по пятую. open HANDLE, "filename.ext"; while (<HANDLE>) { print if (1..5); } 6.3.9.4. Условная операцияУсловная операция это тернарная операция, которая имеет вид: test ? value1 : value2 где test, value1 и value2 любые выражения. Если test истинно, то операция возвращает значение value1, в противном случае она возвращает значение value2. Пример: printf "У меня %d дру%s.\n", $n, ($n == 1) ? 'г' : (($n < 5) ? 'га' : 'зей'); Эта операция может использоваться в левой части операции присваивания, если и value1, и value2 являются переменными, например: ($test ? $a : $b) = $c; 6.3.9.5. Операция запятаяОперация запятая вызывает последовательное вычисление значений двух выражений и возвращает второе из них. Она имеет вид: expr1, expr2 где expr1 и expr2 любые выражения. В списках запятая служит разделителем элементов списка. PERL содержит синоним этой операции вида expr1 => expr2 Такая форма обычно используется для парных элементов списка, например, при инициализации ассоциативных массивов. Кроме того, если левый операнд операции => является словом, то он интерпретируется как строка (см. п. 6.2.7) 6.3.10. Порядок выполнения операцийПри вычислении выражений PERL учитывает приоритет операций: операции, имеющие больший приоритет, выполняются первыми. Для изменения порядка выполнения операций следует пользоваться круглыми скобками: выражение, заключенное в них, имеет наивысший приоритет. В следующей таблице приведен список всех операций языка PERL в порядке убывания их приоритетов; операции, расположенные в одной строке таблицы, имеют равный приоритет и выполняются либо слева направо, либо справа налево, как указано в таблице.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||