Скаляры: числа, строки, sigil $

Разбираемся, что означает загадочный значок $ перед каждой переменной Perl и почему в этом языке число и строка — почти одно и то же.

Скаляр — переменная Perl, которая хранит одно-единственное значение: число, строку текста или ссылку на что-то другое. Знак $ перед именем — это и есть признак скаляра.

Зачем Perl вешает значки на переменные

Если вы раньше писали на Python или JavaScript, первое, что бросается в глаза в коде Perl — странные символы перед именами переменных: $name, @list, %hash. Такой символ называется sigil (от латинского «печать», «знак») — он мгновенно сообщает и человеку, и самому Perl, с каким видом переменной вы имеете дело. В этом уроке разберём первый и самый частый sigil — знак доллара $, который обозначает скаляр.

Идея скаляра простая: это переменная-«коробка», в которую помещается ровно одно значение. Число 5, строка "Привет", результат вычисления — всё это скаляры. Perl был придуман в 1987 году Ларри Уоллом как язык для быстрой обработки текста и системного администрирования, и создатель специально сделал sigil-ы, чтобы при беглом взгляде на код сразу было видно, сколько значений хранит переменная — одно ($) или много (@ и %, о них — в следующих уроках).

Объявление скаляра через my

Чтобы завести новую переменную в современном Perl-коде, её нужно объявить ключевым словом my. Это как let в JavaScript или неявное присваивание в Python — оно говорит: «вот новая переменная, живущая в этом блоке кода».

my $name = "Anya";
my $age = 16;

print "Privet, $name! Tebe $age let.\n";

Вывод:

Privet, Anya! Tebe 16 let.

Разбираем построчно

Строка my $name = "Anya"; объявляет скалярную переменную name и сразу присваивает ей строку "Anya". Обратите внимание: сам знак $ — не часть имени переменной в смысловом плане, а служебный значок «это скаляр», но писать его нужно каждый раз, когда вы обращаетесь к переменной. Строка my $age = 16; объявляет вторую скалярную переменную с числом.

Дальше идёт самое приятное в Perl — интерполяция строк. Если строка заключена в двойные кавычки "...", Perl сам находит внутри неё имена переменных вроде $name и подставляет их значения. Это удобнее, чем склеивать строки через + или f-строки в других языках — не нужен никакой специальный синтаксис, просто пишете $name прямо внутри текста в кавычках, и Perl понимает, что это переменная, а не часть текста. Символ \n в конце строки — перевод строки, точно как в большинстве языков программирования.

Числа и строки — почти одно и то же

Вот что особенно удивляет новичков: в Perl нет строгого разделения на «тип число» и «тип строка», как в Java или C++. Скаляр сам решает, вести себя как число или как текст, в зависимости от того, что вы с ним делаете. Это называется автоматическое преобразование (implicit conversion).

my $x = "10";
my $y = 5;

my $summa = $x + $y;
my $sklejka = $x . $y;

print "Summa: $summa\n";
print "Sklejka: $sklejka\n";

Вывод:

Summa: 15
Sklejka: 1015

Переменная $x хранит строку "10" — обратите внимание на кавычки при объявлении. Но когда мы применяем к ней оператор + (сложение), Perl автоматически «понимает», что здесь нужно число, и превращает строку "10" в число 10 прямо на лету, без каких-либо просьб с нашей стороны. Результат сложения — число 15.

А вот оператор . (точка) в Perl — это не десятичная точка и не доступ к полю объекта, как в других языках, а оператор конкатенации, то есть склейки строк. Когда мы применяем его к тем же переменным, Perl наоборот превращает их в строки и склеивает как текст: "10" плюс "5" через точку даёт не 15, а строку "1015" — просто одна строка приклеена к другой.

Числа как строки: обратное превращение

Работает и в обратную сторону — если число используется там, где ожидается текст, Perl без проблем превращает его в строку символов.

my $ball = 5;
my $opisanie = "Tvoya otsenka: " . $ball . " iz 5";

print "$opisanie\n";

Вывод:

Tvoya otsenka: 5 iz 5

Здесь $ball хранит именно число 5 (без кавычек при объявлении), но оператор . требует строку по обе стороны от себя — и Perl тихо превращает число 5 в текст "5", чтобы склейка вообще получилась. Программисту не нужно писать ничего вроде str(ball), как в Python, или String.valueOf(ball), как в Java — Perl делает это сам, исходя из контекста использования переменной.

Мини-пример: чек в магазине

Соберём идею скаляров в маленькой практической задаче — посчитаем стоимость покупки и выведем аккуратное сообщение.

my $tovar = "Tetrad";
my $cena = 45;
my $kolichestvo = 3;

my $itogo = $cena * $kolichestvo;

print "Tovar: $tovar\n";
print "Cena za shtuku: $cena rubley\n";
print "Itogo za $kolichestvo sht.: $itogo rubley\n";

Вывод:

Tovar: Tetrad
Cena za shtuku: 45 rubley
Itogo za 3 sht.: 135 rubley

Здесь $tovar — скаляр-строка, $cena и $kolichestvo — скаляры-числа, а $itogo — тоже скаляр, в который мы кладём результат умножения. Заметьте: скаляр не «привязан» к одному виду данных навсегда — если бы понадобилось, в $itogo позже можно было бы записать и строку, Perl не станет возражать.

Частые ошибки новичков

Первая и самая частая ошибка — забыть sigil $ при обращении к уже объявленной переменной, например написать просто name вместо $name. Perl в этом случае решит, что вы имеете в виду что-то другое (например, вызов функции с таким именем), и код либо не заработает, либо поведёт себя неожиданно.

Вторая ошибка — перепутать одинарные и двойные кавычки. В двойных кавычках "..." переменные интерполируются (подставляются их значения), а вот в одинарных '...' — нет, там всё воспринимается буквально, включая сам знак $. Если вывод неожиданно показывает $name вместо "Anya", скорее всего, вы использовали одинарные кавычки там, где хотели двойные.

Третья ошибка — путать оператор . (склейка строк) с оператором + (сложение чисел). Начинающие иногда пишут $x + $y, когда на самом деле хотели склеить два текста, и получают неожиданное число вместо строки — или наоборот.

Итоги

  • Скаляр — переменная для одного значения (числа, строки или ссылки), её sigil — знак $.
  • Новые переменные объявляют через my, а внутри двойных кавычек "..." имена переменных автоматически подставляются в текст — это называется интерполяцией.
  • Perl сам превращает число в строку и обратно в зависимости от того, какой оператор применяется: + требует числа, а . — строки.
  • В одинарных кавычках '...' интерполяции не происходит — это частый источник путаницы у новичков.
Проверьте себя
1. Какой sigil (значок) обозначает скалярную переменную в Perl?
A@
B%
C$
D&
2. Что выведет print "$x\n" после my $x = 'Privet';, если использовать одинарные кавычки при объявлении, но двойные при выводе?
AТекст $x буквально, без подстановки
BPrivet — значение подставится, потому что интерполяция зависит от кавычек в команде print, а не в момент объявления переменной
CОшибку компиляции
DПустую строку