Беглое Ознакомление
ru
Это руководство для беглого ознакомления с Perl для неопытных начинающих программистов. В нём предпринята попытка осветить самые основы и выполнено оно в последовательной манере.
Это руководство для быстрого ознакомления с Perl для неопытных начинающих программистов. В нём предпринята попытка осветить самые основы и выполнено оно в последовательной манере.
Попробуем начать с простого примера. Это общепринятый пример во всех пособиях и книгах по программированию, и он печатает "Привет Мир". Попробуйте выполнить следующую программу, вы должны увидеть вывод.
say 'Hello, world!'
В данном случае say
- это функция, которая принимает аргументы и печатает их на экран.
Попробуйте исправить следующий код, чтобы он начал печатать 'Пока':
say ''
__TEST__
like($stdout, qr/Пока/, 'Должен напечатать Пока');
Часто программисты допускают ошибки, которые вполне допустимы с точки зрения синтаксиса языка, но имеет логические изъяны, которые создают трудно- диагностируемые проблемы.
Чтобы определять опечатки и разные подводные камни, Perl предоставляет две крайне полезные прагмы strict
и warnings
. Они рекомендуются к использованию в каждой программе. Все примеры в данном руководстве подразумевают наличие этих двух строчек и они опускаются для экономии места.
Вам не обязательно понимать следующий код, просто отметьте разницу при использовании прагм безопасности
use strict;
use warnings;
$x += 1;
$y .= 'string';
say 'ok';
и не использовании их
no strict;
no warnings;
$x += 1;
$y .= 'string';
say 'ok';
Числа бывают целыми (1, 2, 5) или дробными (1.2, 1e5). Между ними нет никакой разницы. Perl считает их однотипными и автоматически конвертирует.
Попробуйте напечатать следующие числа:
say 1;
say 4.4;
say 1.2e10;
Как вы можете видеть все инструкции завершаются символом ;
. Это по смыслу соответствует точке, которой мы разделяем предложения.
Базовые арифметические операции включают: +
(сложение), -
(вычитание), *
(умножение), /
(деление), **
(возведение в степень) и %
(модуль числа).
say 1 + (10/5) * 3
Выведите результат возведения 5 в степень 6.
say
__TEST__
like($code, qr/\*\*/, 'Нужно использовать оператор **');
like($stdout, qr/15625/, 'Должно получиться 15625');
Строки объявляются с использованием одинарных или двойных кавычек. Разница сейчас нам не важна. В нашем первом примере 'Привет, мир!'
являлось строкой.
say 'foo'
Строки могут быть сцеплены (склеены) с использованием оператора .
say 'foo' . 'bar'
Оператором x
вы можете повторять строки.
say 'foo' x 3;
Обычно вам может потребоваться работать со строками, чтобы вычислить их длину, найти определённый символ или подстроку и т.д. Набор базовых функций для работы со строками включает в себя length(), substr(), index(), rindex().
say length 'foo';
say substr 'foo', 1, 2;
say index 'foo', 'o';
say rindex 'foo', 'o';
Выведите номер позиции строки 'ball'
в строке 'Football'
.
say
__TEST__
like($code, qr/index/, 'Нужно использовать функцию index');
like($stdout, qr/4/, 'Должен получиться номер позиции 4');
Списки - это, как ни странно, список значений. Объявляются списки с использованием скобок.
say (1, 2, 3, 5)
Часто лучше использовать диапазоны, чтобы не печатать много:
say (1 .. 5)
Тоже самое работает и с символами.
Выведите список символов от 'b'
до 'm'
.
say
__TEST__
like($stdout, qr/bcdefghijklm/, 'Должно напечатать bcdefghijklm');
Списки конечно могут содержать не только числа, но и строки:
say (1, 'привет', 2, 'там')
Списки, используемые внутри списков, разворачиваются:
say (1, (2, 3, 4), 5)
Присвоение в языках программирования - это операция сохранения значения в какой-либо области памяти компьютера, которое может быть извлечено по его имени.
В Perl 5 есть три встроенных типа данных: скаляры, массивы и хэши (или ассоциативный массив). Скаляры могут хранить строки или числа. Массивы хранят список скаляров, где значения извлекаются по номеру индекса. Хэши - это неупорядоченный ассоциативный массив, где значения доступны по ключам. Переменные, которые содержат скаляр, массив или хэш, обозначаются с префиксом $
, @
и %
соответственно.
Переменные обычно объявляются использованием ключевого слова my
. Например:
my $x = 1;
say $x;
Присвойте переменной y
строку 'Примет, мир!'
и напечатайте её.
my $
say
__TEST__
like($stdout, qr/Привет, мир!/, 'Должно напечатать "Привет, мир!"')
В зависимости от того, что содержит переменная (число или строку), используются различные операторы.
Если, скажем, вы хотите сложить два числовых значения:
my $x = 1;
my $y = 2;
say $x + $y;
Или вы хотите соединить два строковых значения:
my $x = 'Hello';
my $y = 'There';
say $x . $y
Если вы попытаетесь использовать +
на строках или .
на числах, они автоматически будут конвертированы в соответствующий тип.
my $x = 1;
my $y = '2 times';
say $x . $y;
say $x + $y;
Как вы можете видеть, во втором примере строка '2times' была конвертирована в число 2.
Объедините и выведите строки 'Результат='
и сумму чисел 42
и 13
.
my $x = ;
my $y = ;
say
__TEST__
like($stdout, qr/55/, 'Дожно напечатать "Результат=55"');
Массивы могут хранить список скаляров.
my @array = (1, 2, 3);
say @array;
Основные операции над массивами включают в себя получение элемента массива по индексу (начиная с 0), получение индекса последнего элемента, извлечение и помещение элементов.
my @array = (1, 2, 3);
# Получить третий элемент
say $array[2];
# Получить индекс последнего элемента
say $#array;
push @array, 4;
say @array;
pop @array;
say @array;
shift @array;
say @array;
unshift @array, 0;
say @array;
Как вы должно быть заметили, когда мы получаем элемент массива, мы изменяем @
на $
, поскольку элемент массива это скаляр, а скаляры предваряются символом $
.
Создайте массив, который содержит список (1, 2, 3, 4)
, и выведите его третий элемент.
my @array = ;
say
__TEST__
like($stdout, qr/3/, 'Должно напечатать 3')
Хэш или ассоциативный массив - это неупорядоченный набор скаляров, который может быть извлечён по ключу. Ключ обычно является строкой.
my %hash = ('key1', 'value1', 'key2', 'value2');
Вместо использования запятой, для разделения ключей и значений, Perl предоставляет более читаемый оператор =>
, например:
my %hash = (key1 => 'value1', key2 => 'value2');
Базовые операции над хэшем
Так же как и массивами, при получении значения ключа хэша переменная становится скаляром и мы используем символ $
и скобки {}
:
my %hash = (key1 => 'value1', key2 => 'value2');
say $hash{key1};
my %hash = (key1 => 'value1', key2 => 'value2');
say keys %hash;
say values %hash;
Контекст - очень важное понятие в Perl. Существуют два основных контекста: скалярный и списочный. Контекст обычно влияет на то, как ведут себя функции и переменные. Это весьма близко к поведению естественного языка.
Наиболее популярное использование - получение длины массива, например. Обычно, когда вы используете массив в списочном контексте, он возвращает все свои элементы, но когда вы используете его в скалярном контексте, он возвращает свою длину.
my @array = (1, 2, 3);
my @array2 = @array; # списочный контекст
say @array2;
my $length = @array; # скалярный контекст
say $length;
Перед тем как мы представим соответствующие операторы Perl, расскажем основы булевой алгебры.
Булева алгебра - это вид алгебры, где вместо чисел используются значения истинности 0
и 1
, где 1
называется истиной
и 0
называется ложью
.
Как и в обычной алгебре, есть такие операции как +
, *
и т.д., но базовые же называются НЕ
, И
и ИЛИ
. Как вы уже знаете, в Булевой алгебре у нас есть только значения Истина
и Ложь
. Это означает, что они не только используются в операциях, но и результаты операций также являются Истиной
и Ложью
. Давайте рассмотрим их по очереди.
В Perl нет значений Истина
и Ложь
. В Perl под Истиной
понимается всё, что не является Ложью
, где Ложь
это всё что угодно, что конвертируется в 0
, например: 0
сам по себе, ''
(пустая строка), undef
.
Оператор НЕ
- это унарный оператор, что означает, что он оперирует над одним значением. В Perl оператор НЕ
обозначается !
. Таблица истинности НЕ
:
x | !x |
0 | 1 |
1 | 0 |
Рассмотрим результаты действия этого оператора на различные значения. В следующем примере мы добавляем 0
к значению Ложь
, чтобы оно не было конвертировано функцией say
в пустую строку.
say !0;
say !1 + 0;
say !'строка, которая конвертируется в 1' + 0;
say !'';
Оператор И
- бинарный оператор, что означает, что он действует на два значения. В Perl оператор И
обозначается &&
. Таблица истинности И
:
x | y | && |
0 | 0 | 0 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 1 |
Рассмотрим, какие результаты получаются при использовании этих операторов на различные значения. В следующем примере мы добавляем 0
к значению Ложь
, чтобы оно не конвертировалось в пустую строку функцией say
.
say 1 && 1;
say 0 && 1;
say 0 && 0;
say 'строка' && 1;
Оператор ИЛИ
также бинарный оператор, что означает, что он оперирует над двумя значениями. В Perl оператор ИЛИ
обозначается ||
. Таблица истинности ИЛИ
:
x | y | || |
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 1 |
Рассмотрим, какие результаты получаются при использовании этих операторов на различные значения. В следующем примере мы добавляем 0
к значению Ложь
, чтобы оно не конвертировалось в пустую строку функцией say
.
say 1 || 1;
say 0 || 1;
say 0 || 0;
say 'строка' || 0;
Как и в нормальной алгебре в Булевой алгебре есть свои приоритеты, когда разные операторы вычисляются раньше, чем остальные. Порядок Булевых операторов:
# запускать не надо
! && ||
НЕ
, И
и ИЛИ
могут быть комбинированны друг с другом. Вы можете использовать скобки для изменения порядка логических вычислений:
say (1 || 0) && 1
Исправьте следующее выражение расставив скобки так, чтобы печаталась пустая строка, вместо 1
.
say !1 || 1 && 1
__TEST__
is($stdout, "\n", 'Должна быть пустая строка');
Операторы сравнения также возвращают Истину
и Ложь
, но используются с числами и строками. Так как Perl не различает числа и строки, есть две различные группы операторов для чисел и строк.
== | != | < | <= | > | >= |
eq | ne | lt | le | gt | ge |
Попробуем данный пример:
say 1 == 1;
say 10 > 2;
say 3 <= 3;
say 'foo' ne 'bar';
Условные операторы позволяют вам изменять ход выполнения кода. Условные операторы работают с Булевыми значениями, которые вы изучили в предыдущей главе, их набор состоит из if/else/elsif
и unless
.
Если результат выражения в скобках истинный, тогда вычисляется блок программы, окружённый фигурными скобками:
if (1 == 1) {
say 'Истина';
}
if (1 == 0) {
say 'Ложь';
}
Если вы хотите что-нибудь сделать, когда выражение ложно, вы можете использовать else
:
if (0) {
say 'Истина';
}
else {
say 'Ложь';
}
Если вы хотите ещё раз выполнить проверку выражения, используйте elsif
:
my $x = 1;
if ($x == 0) {
say 'x это ноль';
} elsif ($x < 0) {
say 'x меньше нуля';
} else {
say 'x больше нуля';
}
Существует также короткая форма записи оператора if
:
my $x = 5;
say 'Истина' if $x > 0;
unless
противоположен if
, когда не истинное значение приводит к выполнению блока, а наоборот - ложное.
my $x = 5;
say 'Истина' unless $x == 0;
Что эквивалентно:
my $x = 5;
say 'Истина' if !($x == 0);
Как вы уже знаете, в Perl истинное выражение это всё что угодно, кроме нуля, поэтому сравнение с 0 обычно не требуется:
my $x = 5;
say 'Истина' unless $x;
Исправьте этот код так, чтобы он печатал 'Привет'
, вместо 'Пока'
, используя только логический оператор без изменения значения $x
.
my $x = 0;
if ($x) {
say 'Привет';
}
else {
say 'Пока';
}
__TEST__
like($code, qr/\$x = 0/, 'Не должно меняться значение $x');
like($stdout, qr/Привет/, 'Должен вывести "Привет"');
Циклы - это блоки, которые выполняются несколько раз. Они обычно используются для повторяющихся действий, обхода через структуру данных и прочего.
Цикл Foreach
обычно используется для прохода через список или массив. Например:
foreach my $element (1, 2, 3, 4, 5) {
say $element;
}
Вы, конечно, можете передать массив:
my @array = (1 .. 5);
foreach my $element (@array) {
say $element;
}
Как вы видите, мы создали специальную переменную $element
, которая ссылается на соответствующий элемент массива при каждой итерации. Будьте внимательны, изменяя значение $element
вы меняете значение элемента в массиве:
my @array = (1 .. 5);
foreach my $element (@array) {
$element *= 2;
}
foreach my $element (@array) {
say $element;
}
Выведите только чётные значения от 0
до 10
:
foreach my $element (...) {
if (...) {
...
}
}
__TEST__
like($stdout, qr/0\n2\n4\n6\n8\n10/, 'Должны быть выведены только чётные значения');
While
- это наиболее продвинутый цикл, который выполняется пока значение истинно.
my $i = 10;
while ($i > 0) {
say $i;
$i = $i - 1;
}
Как только выражение $i > 0
становится ложью цикл завершается.
Выведите только нечётные значения от 0
до 10
:
my $i = ;
while ($i ...) {
if (...) {
...
}
}
__TEST__
like($stdout, qr/1\n3\n5\n7\n9/, 'Должны быть выведены только нечётные значения');
Часто может потребоваться завершить цикл не дожидаясь пока он закончится. Обычно вы можете использовать ключевое слово last
:
my $i = 0;
while ($i < 100) {
last if $i == 10;
say $i;
$i = $i + 1;
}
Этот цикл не будет выполняться 100
раз, поскольку мы завершим его, когда $i
сравняется с 10
.
Наиболее используемая специальная переменная - это $_
, которая является скалярной переменной по-умолчанию. Чтобы лучше понять её, рассмотрим примеры.
Вы знакомы с функцией say
. Она выводит всё, что вы передадите ей как аргумент. Но что произойдёт, если вы не передадите ей аргумента? Она возьмёт значение из переменной по-умолчанию $_
.
$_ = 'Привет';
say;
Конечно вам обычно не требуется такая функциональность, но она полезна, когда используются циклы, например:
say for (1 .. 10);
По-умолчанию цикл for
устанавливает переменную $_
и say
выводит её.
Многие встроенные Perl функции используют переменную по-умолчанию, в том случае если не переданы аргументы.
Подпрограммы - это функции, которые принимают аргументы и возвращают результат. Обычно подпрограммы используются для того, чтобы избежать дублирование кода, делая его простым и более понимаемым.
Например, вам требуется конвертировать 5 миль в километры. Вы можете написать что-нибудь такое:
# Конвертировать 5 миль в километры
say 5 * 1.609344
Но если вам потребуется конвертировать 10 миль в километры или другое произвольное число? В этом случае мы создаём подпрограмму, которую мы можем использовать позже.
sub miles_to_kilometers {
my ($miles) = @_;
return $miles * 1.609344;
}
say miles_to_kilometers(5);
say miles_to_kilometers(10);
say miles_to_kilometers(42);
Запись подпрограммы требуют небольшого пояснения. my ($miles) = @_
- это так называемая распаковка аргументов
. В Perl аргументы передаются через массив по-умолчанию @_
(это тоже специальная Perl переменная, также как и $_
). Конечно же вы можете применять любые специфичные для массивов функции над массивом по-умолчанию.
Напишите и используйте подпрограмму, которая конвертирует километры в мили, и выведите значения 4, 6, 19 километров конвертированных в мили (один километр это 0.621371192 миль).
sub kilometers_to_miles {
my ...
return ...
}
say kilometers_to_miles(4);
say kilometers_to_miles(6);
say kilometers_to_miles(9);
__TEST__
like($stdout, qr/2.485484768\n3.728227152\n5.592340728/,
'Должно вывести корректные значения')
Viacheslav Tykhanovskyi, vti@cpan.org
Vladimir Lettiev crux@cpan.org