11. Что такое \ в Perl 6

В перле есть три основных сигила — $, @ и %. Сюда еще можно добавить & и \ и несколько вариантов твигилов типа $? или $*. Сегодня же поговорим только об обратном слеше.

Это довольно нетипичная для обычного программирования штука, которая, однако, очень широко применятся во внутренностях 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

Обратный слеш связывает аргумент с объектом, в данном случае, с константой, которую функция попыталась изменить. Это оказалось невозможно, поэтому и произошла ошибка.

Завтра мы продолжим с этого места и поговорим о том, как записать \ другими словами.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *