В перле есть три основных сигила — $, @ и %. Сюда еще можно добавить & и \ и несколько вариантов твигилов типа $? или $*. Сегодня же поговорим только об обратном слеше.
Это довольно нетипичная для обычного программирования штука, которая, однако, очень широко применятся во внутренностях Rakudo Perl 6. Рассмотрим пример:
sub add(\a, \b) { a + b } my $a = 10; my $b = 20; say add($a, $b); # 30 say add(3, 4); # 7
На что здесь следует обратить внимание. Во-первых, параметры функции — переменные без сигила. Код для вычисления суммы двух значений — a + b, совсем не как обычно принято в перле: $a + $b.
Дальнейший код, казалось бы, не содержит никаких подводных камней. Однако, все меняется, если функция попытается изменить свои аргументы:
sub add(\a, \b) { a++; b++; return a + b; }
Использование такой функции с переменными продолжает работать:
my $a = 10; my $b = 20; say add($a, $b); # 32 say $a; # 11 say $b; # 21
Переменные, однако, изменились после возвращения из функции. То есть в данном случае слеш похож по действию на ссылку в Perl 5.
Теперь попробуем вызвать функцию напрямую с константами:
say add(3, 4);
Эта короткая строка не то что не выполняется, но и выдает довольно объемное сообщение об ошибке:
Cannot resolve caller postfix:<++>(Int); the following candidates match the type but require mutable arguments: (Mu:D $a is rw) (Int:D $a is rw) The following do not match for other reasons: (Bool:D $a is rw) (Bool:U $a is rw --> Bool::False) (Mu:U $a is rw) (Num:D $a is rw) (Num:U $a is rw) (int $a is rw) (num $a is rw --> num) in sub add at bind-1.pl line 2 in block at bind-1.pl line 13
Обратный слеш связывает аргумент с объектом, в данном случае, с константой, которую функция попыталась изменить. Это оказалось невозможно, поэтому и произошла ошибка.
Завтра мы продолжим с этого места и поговорим о том, как записать \ другими словами.