Анонимный хеш (хеш без имени)
— В процессе вычисления блока создается ссылка на анонимный массив из одного элемента, что является результатом вызова функции uc();
— При разыменовании ссылки на анонимный массив результат интерполируется внутри строки.
Анонимный хеш (хеш без имени)
Для их создания применется специальный генератор — это пара фигурных скобок. Например,
$ref_hash = {
Name => Vova,
ID => 1234
};
Здесь создан анонимный хеш, в котором ввели две пары ключ/значение и поместили ссылку на хеш в скалярную переменную $ref_hash.
Для использования хеша надо ссылку разыменовать:
print $$ref_hash {Name};
Можно применить и оператор-стрелку:
print $ref_hash -> {Name};
В результате в этих примерах будет выведено — Vova.
Анонимная подпрограмма (подпрограмма без имени)
Для этого применяется генератор – ключевое слово sub. Например,
$ref_subr = sub { print "Hello! n"};
Внимание!
Необходимо обратить внимание на то, что здесь в конце команды поставлена точка с запятой, тогда как в случаях обычных подпрограмм этого делать не надо.
Для разыменования этой ссылки надо применить префикс &.
Прмер:
$ref_subr = sub { print "Hello! n"};
&ref_subr;
Будет выведено — Hello!
Если подпрограмма использует аргументы, то можно сделать так:
$ref_subr1 = sub {print shift};
&{$ref_subr1} ("Hello! n");
Или таким образом:
$ref_subr1 = sub {print shift};
&{$ref_subr1} — > ("Hello! n");
В результате будет выведено — Hello!
Ссылки позволяют создать массив подпрограмм. Пусть есть следующие две подпрограммы:
sub F1
{ ……..}
sub F2
{ ……..}
Создаем таблицу диспетчирезации, содержащую ссылки на подпрограммы:
$arr[0] = &F1;
$arr[1] = &F2;
Теперь с помощью индекса можно выбирать, какую подпрограмму вызывать:
print &{$arr[1]};
или
print &{$arr[0]} ("String_1",100); # Здесь два аргумента подпрограммы F1.
Определение типа ссылки с помощью оператора ref
Оператор ref опоределяет – на элемент какого типа ссылается ссылка.
Синтаксис:
ref вырвжение
ref
Оператор возвращает истина ( ненулевое значение ), если выражение – это ссылка, и ложь – иначе. Если выражение нет, то оператор работает с переменной $_. При истине отражается тип элемента, на который ссылается ссылка. Это может быть:
REF
SCALAR
ARRAY
HASH
CODE
GLOB
Пример:
$a = 5;
$ref_a = $a;
print (ref $ref_a);
Будет выведено SCALAR.
Операторы
1. Блок операторов
Это последовательность операторов, заключенная в парные фигурные скобки.
{ 1-й оператор
2-й оператор
………………………………
Последний оператор
}
Вместо оператора всегда может быть блок. Последняя (;) не обязательна
2. Оператор if/unless
А. if (выражение) {блок} else {блок};
Как и в других языках else можно опускать
Б. Если надо оставить только else, то применяется unless. То-есть если выражение ложно, то делать.
В. Если много вариантов, то можно вместо if применять elsif.
3. Оператор while/until
Это операторы цикла
A. while (выражение) {блок};
Пока выражение истина, то выполняется блок
Б. until (выражение) {блок};
Если выражение ложь, то выполняется блок.
Эти операторы проверяют условие в начале каждого цикла, до входа в него.
4. Оператор do{}while/until
Применяют для того, чтобы проверить условие не в начале, а в конце цикла.
А. do {блок} while выражение;
Б. do {блок} until выражение;
5. Оператор for
for (начальное_выражение; проверочное_выражение; возобновляющее_выражение)
{блок}
Как в Си
6. Оператор foreach
foreach $переменная_цикла (@список) {блок};
Переменной цикла каждый раз присваивается значение из списка и выполняется блок. Переменные цикла локальные для данного цикла.
Имя переменной цикла можно опустить, тогда цикл будет работать со встроенной переменной $_. Переменная $_ применяется во многих конструкциях Perl.
Пример:
@a=(1,2,3,4,5);
foreach $b(reverse @a)
{ print $b};
Будет выдано 5 4 3 2 1
Можно так:
@a=(1,2,3,4,5);
foreach (reverse @a)
{print};
Будет выдано то же самое.
Внимание!!
Если список в цикле состоит из переменных, то переменная цикла – это псевдоним для каждой переменной этого цикла, а не копия ее значения. Поэтому, меняя значение переменной цикла, мы будем менять конкретный элемент в списке, который ей соответствует.
Пример:
@a=(3,5,7,9);
foreach $n (@a)
{ $n*=3 };
Получим список @a равен
(9,15,21,27)
7. Операторы прерывания цикла
А. Оператор last
Обеспечивает выход из самого внутреннего цикла, в котором расположен этот оператор, передавая управление оператору, следующему непосредственно за этим циклом.
Пример:
while (выражение)
{ операторы;
if (условие)
{ операторы;
last; => выход из цикла while
}
операторы;
}
# last передает управление сюда
Б. Оператор next
Заставляет прервать выполнение операторов итерации цикла. Т. е. цикл не завершается
Пример:
while (условие)
{ операторы;
if (условие)
{ операторы;
next;
}
операторы
#next передает сюда управление
}
В. Оператор redo
Передает управление в начало итерации цикла без повторного вычисления условия.
Пример:
while (условие)
{ #redo передает управление сюда
Операторы;
if (условие)
{ операторы;
redo;
}
Операторы;
}
Внимание!
С точки зрения операторов last, next, redo оператор типа do{}while/until циклом не считается. Учитываются только циклы for foreach while until.
Для прерывания вложенных циклов используются эти операторы прерывания с метками.
Метка – обыкновенное имя без префиксного знака. В имени должны быть ПРОПИСНЫЕ БУКВЫ и цифры.
Пример:
OUTER: for ($i=1;$i<=10;$i++);
{ INNER:
for($j=1;$j<=10;$j++)
{if ($i*$j==63)
print "$i times $j id 63!n";
last OUTER
}
if ($j<=$i)
{ next INNER
} #конец цикла по j
} #конец цикла по i
Здесь происходит перемножение чисел до тех пор, пока результат не будет равным 63=9*7. Когда получим 63, дальнейших действий не делаем. Поэтому last для всех циклов. Оператор next INNER не дает перемножать числа при j>i.
Вывод:
1. Метка с двоеточием ставится перед циклом, который надо прервать.
2. С помощью метки нельзя входить в цикл – можно только выходить из него.
3. Операторы last next redo должны находиться внутри блока цикла
8. Модификаторы выражений
Применяют для более удобной записи условных операторов.
А. Выраж_2 if Выраж_1
Если Выраж_1 истинно, то выполняется Выраж_2. То-есть этот оператор удобно читать справа налево. Он эквивалентен if (Выраж_1) {Выраж_2};
Б. Выраж_2 unless Выраж_1
Эквивалентно unless (Выраж_1) {Выраж_2}
В. Выраж_2 while Выраж_1
Эквивалентно while (Выраж_1) {Выраж_2}
Г. Выраж_2 until Выраж_1
Эквивалентно until (Выраж_1) {Выраж_2}
Пример:
Найти первую по порядку степень числа 2, которая больше заданной.
chomp ($n=<STDIN>)
$i=1;
$i*=until $i>$n;
Внимание!
Нельзя вкладывать одну форму записи в другую. Например:
Выр3 while Выр2 if Выр1
Это будет уже оператором.
9. Операторы && и ||
Для реализации "если это, тогда то" мы знаем следующие конструкции:
А. if (это) {то};
Б. то if это
Рассмотрим еще один вариатн.
В. это && то;
Когда "это" истинно, то надо выполнить "то". Если "это" – ложно, то второе выражение "то" уже не определяется.
Аналогично для замены unless (это){то} можно применять это||то
Базовые средства ввода-вывода
Ввод из STDIN
1. При вводе в скаляр мы получаем следующую строку ввода до символа "конец строки" или undef, если строк больше нет.
$a=<STDIN>
2. При вводе в массив – получаем все оставшиеся строки в виде списка, любой элемент которого — одна строка, которая включает символ n
@a=<STDIN>;
Для чтения всех строк по одной с последующей обработкой каждой из строк применяется цикл:
1. while (defined ($line=<STDIN>))
{ обработка $line
}
Если строк нет, то операция чтения возвращает значение undef.
2. Можно так:
while (<STDIN>) # Это эквивалентно ($_= <STDIN>)