Операторы
В перле существуют традиционные правила приоритета выполнения операторов , например :
print 1, 2, 3, 4, sort 9, 8, 7, 6, 5;
Сначала в этом примере будет выполнена стандартная функция sort для списка аргументов ,
после чего будет выведен общий список :
123456789
Оператор-стрелка -> заимствован из языка C .
В примере создается ссылка на хэш с помощью оператора \,
после чего с помощью -> обеспечивается доступ к элементу хэша :
$hash{fruit} = apple;
$hash{sandwich} = hamburger;
$hash{drink} = bubbly;
$hashref = \%hash;
print $hashref -> {sandwich};
Операторы инкремента ++ и дикремента -- работают также , как и в си .
Оператор возведения в степень - **.
Оператор связывания =~ связывает скалярную переменную с операцией поиска-замены по шаблону -
s/.../.../, m/.../, tr/.../ .
Например :
$line = ".Hello!";
if ($line =~ m/^\./)
{ print "Should't start a sentence with a period!"; }
Оператор x дублирует действие , например :
@ones = (1) x 80;
будет создан список из 80 единиц .
Следующий пример заменяет все единицы на пятерки :
@ones = (5) x @ones;
Оператор конкатенации . связывает 2 строки :
print "Hello " . "there.";
Операторы работы с файлами :
-e - существование файла
-A - время последней модификации
-b - блочный файл
-B - двоичный файл
-d - каталог
-l - символическая ссылка
-o - файл принадлежит текущему пользователю
-p - пайп
-r - на чтение
-s - размер файла
-S - сокет
Операторы сравнения :
== - равно
!= - не равно
<=>
- числа -1 , 0 , 1 в зависимости от того , является ли левый операнд меньше , равен или больше правого
eq - равенство строк
ne - неравенство строк
&& - логическое И
|| - логическое ИЛИ
Оператор диапазона (..)
Например for (1..5)
@alphabet = ('A' .. 'Z');
Тернарный условный оператор ?: требует 3-х операторов :
print 5 >= 0 ? "больше нуля" : "меньше нуля";
Список разрешенных «коротких» операторов присвоения выглядит как
**=
+=
*=
&=
<<=
&&=\
-=
/=
|=
>>=
||=
.=
%=
^=
x=
Оператор-запятая работает по-разному для скаляра и вектора :
$variable = (3, 4, 5);
print $variable;
5
@array = (3, 4, 5);
print join(", ", @array);
3, 4, 5
Условный оператор :
if ($ppp==0)
{
$pm[0] = $plusgif ;
}
elsif (($ppp==211) or ($ppp==212))
{
$dv[0] = $divclose;
}
else
{
$pm[0] = $minusgif ;
$dv[0] = $divopen;
}
Команда unless (выражение) {блок} является противоположнстью оператора if ,
и блок выполняется тогда , когда выражение = false .
Операторы цикла :
while
for
foreach
until
Оператор for (выражение1; выражение2; выражение3) {блок} :
for ($loop_ind = 1; $loop_ind <= 5; $loop_ind++) {
print "Hello!\n"
}
В следующем примере из входного потока данных STDIN считываются
и выводятся строки до тех пор,
пока не встретится строка,начинающаяся с букв q или Q :
for ($line = <>; $line =~ /^q/i; ; $line = <> {
print $line;
}
@array = ("Hello ", "there.\n");
for (@array) {print;}
Оператор foreach переменная (список) {блок} :
$hash{fruit} = orange;
$hash{sandwich} = clubburger;
$hash{drink} = lemonade;
foreach $key (keys %hash) {
print $hash{$key} . "\n";
}
@array = (1, 2, 3);
foreach $element (@array) {
$element += 1;
}
print join(", ", @array);
Оператор while (выражение) {блок} continue {блок’} :
$savings = 0;
while ($savings < 1_000_000) {
print "Enter the amount you earned today: ";
$savings +- <>;
}
$hash{fruit} = orange;
$hash{sandwich} = clubburger;
$hash{drink} = lemonade;
while (($key, $value) = each(%hash)) {
print "$key => $value\n";
}
$loop_index = 1;
while ($loop_index <= 5) {
print "Hello!\n";
} continue {
$loop_index++;
}
Оператор until (выражение) {блок} continue {блок’}
$loop_index = 1;
until ($loop_index > 5) {
print "Hello!\n";
} continue {
$loop_index++;
}
В Perl разрешается перейти к следующей итерации любого внешнего цикла,
если для него определена метка и вы находитесь в теле цикла.
OUTER: for ($outer = 0; $outer < 10; $outer++) {
$result = 0;
INNER: for ($inner = 0; $inner < 10; $inner++) {
$result += $inner * $outer;
next OUTER if $inner == $outer;
print "$result\n";
}
}
Double-Quoted Strings
Здесь описывается поведение перловых строк , квотированных двойными кавычками .
Оригинальная статья была написана Jason King для версии Perl 5.6.0.
Нужно вспомнить фразу Randal L. Schwartz о том ,
что перл интерполирует только переменные ,
а не выражения .
Рассмотрим примеры :
#!/usr/bin/perl -wl
use strict;
my @a=(1000, 10, 20, 30, 40, 50, 60);
my $i=2;
my $f=sub { return 4 };
my $r=\@a;
print "$i";
print "$a[0]";
print "@a";
print "$i+1";
print "$a[$i+1]";
print "$a[$i+1]+1";
print "$f->()+1";
print "$r->[1]";
print "$a[$f->()+1]+1";
print "@a[2..$f->()]";
Вывод будет такой :
print "$i"; # Output: 2
Это пример простой интерполяции .
print "$a[0]"; # Output: 1000
Немного посложнее , $a[0] - все та же переменная .
print "@a"; # Output: 1000 10 20 30 40 50 60
@a - это переменная , представляющая массив .
print "$i+1"; # Output: 2+1
А вот тут уже неполная интерполяция - вместо ожидаемой тройки мы получаем 2+1
print "$a[$i+1]"; # Output: 30
Пятый результат выглядит более логичным ,
нежели предыдущий , поскольку мы получаем ожидаемый
результат $a[3]=30 .
print "$a[$i+1]+1"; # Output: 30+1
Снова невпопад - вместо 31 мы получаем 30+1
print "$f->()+1"; # Output: CODE(0x9f9b8c)->()+1
Результат , на первый взгляд , довольно странный .
print "$r->[1]"; # Output: 10
$r - ссылка на массив , и мы получаем ожидаемый второй элемент этого массива .
print "$a[$f->()+1]+1"; # Output: 50+1
Выражение в скобках $f->()+1 , в отличие от примера 7 , на этот раз
интерполируется , поскольку заключено в квадратные скобки , и приобретает значение ,
равное 5.
print "@a[2..$f->()]"; # Output: 20 30 40
@a[something] есть массив , и выражение в квадратных скобках
2..$f->() интерполируется в результат (2,3,4) .
Еще несколько примеров :
my %h=(foo=>'bar', bar=>'baz');
my $s='foo';
print "$h{'foo'}";
print "$h{$s}";
print "$h{$h{$s}}";
print "$h{\"$h{$s}\"}";
print "$h{'foo'}"; # Output: bar
Hash-элемент интерполируется в переменную , ничего странного .
print "$h{$s}"; # Output: bar
Аналогично .
print "$h{$h{$s}}"; # Output: baz
Это уже интереснее - происходит двойная интерполяция , и мы имеем :
$h{$s} интерполируется в $h{bar} .
print "$h{\"$h{$s}\"}"; # Output: baz
Почти то же самое
print "$h{'$h{$s}'}"; # Output: Use of uninitialized value at - line 28.
Ups - иксэпшн .
'$h{$s}' - выражение в одинарных скобках не интерполируется .
Рассмотрим несколько примеров :
#!/usr/bin/perl -wl
# leave out the 'use strict' this time
my $a = 4; # a simple scalar
print "$a+5"; # Output: 4+5
Результат банальный .
print "$a[0]"; # Output: Use of uninitialized value at - line 2.
print "$a{name}"; # Output: Use of uninitialized value at - line 2.
А вот здесь уже видно , что перл не делает никакой разницы
между квадратными и фигурными скобками при интерполяции .
print "$a["; # Output: Missing right bracket at - line 2, within string
print "$a{"; # Output: Missing right bracket at - line 2, within string
Сказавши а - скажи б .
print "$a->["; # Output: Missing right bracket at - line 2, within string
print "$a->{"; # Output: Missing right bracket at - line 2, within string
Поскольку есть открывающие скобки -
то и должно быть интерполирующее выражение в них .
print "$a" . "["; # Output: 4[
print "$a" . "{"; # Output: 4{
Здесь интерполяция выполняется прежде конкатенации ,
и поскольку нечего интерполировать ,то и ошибки нет .
print "${a}["; # 5.005_03 Output: 4[
# 5.6.0 Output: Name "main::a" used only once: possible typo at - line 3.
Use of uninitialized value in concatenation (.) at - line 3.
[
print "${a}{"; # 5.005_03 Output: 4{
# 5.6.0 Output: Name "main::a" used only once: possible typo at - line 3.
Use of uninitialized value in concatenation (.) at - line 3.
{
Здесь на примере 2-х разных версий перл видно , что в более ранней версии 5.005
все проходит гладко ,а в более старшей 5.6 возникает ошибка .
Проверьте это у себя .
|