Подтвердить что ты не робот

Необычный синтаксис Perl

Мне нужно внести изменения в Perl script, и это моя первая попытка понять Perl. Я вижу следующее:

my %trades;
...
foreach my $row (@$rows) {
  @{$trades{pop @$row}} = @$row;
}

Я запутался в этом, потому что кажется, что мы выталкиваем последний элемент массива @$row и устанавливаем хэш-ключ %trades как элемент, который был выскользнут, и значение @$row.

Правильно ли это понимание?

4b9b3361

Ответ 1

Чтобы понять этот фрагмент кода, нам нужно избегать трех вещей:

  • Порядок оценки:

    EXPR_A = EXPR_B
    

    оценивает EXPR_B перед оценкой EXPR_A.

  • Копирование семантики:

    @new_array = @old_array
    

    копирует значения @old_array на @new_array.

  • Разъявление сложных структур данных:

    @{ $trades{$key} }
    

    обращается к записи с именем $key в хеше %trades и рассматривает ее как ссылку на массив.

Вместе ваш код эквивалентен этому:

foreach my $row (@$rows) {
  my @copy = @$row;
  my $key = pop @$row;
  @{ $trades{$key} } = @copy;
}

(сохраняя при этом все побочные эффекты)

Итак, например

$rows = [
  [1, 2, "keyA"],
  [3, 4, "keyB"],
];

создаст

%trades = (
  keyA => [1, 2, "keyA"],
  keyB => [3, 4, "keyB"],
);
$rows = [
  [1, 2],
  [3, 4],
];

Тот, кто написал эту строку, имел очень точные знания об оценочном порядке и любит пытать программистов-технологов.

Ответ 2

Цикл эквивалентен

my %trades = map { $_->[-1] => [ @$_ ] } @$rows

за исключением того, что этот способ @$rows остается неизменным. ИМО это должно быть написано именно так.