Как объединить массивы псевдонимов в Perl? - PullRequest
6 голосов
/ 07 октября 2010

Как вы объединяете массивы псевдонимов в Perl так, что результирующий массив также содержит псевдонимы?

Решение, которое я придумал:

my ($x, $y, $z) = 1 .. 3;

my $a1 = sub {\@_}->($x);

my $a2 = sub {\@_}->($y, $z);

my $a3 = sub {\@_}->(@$a1, @$a2);

say "@$a3";  # 1 2 3

$_++ for $x, $y, $z;

say "@$a3";  # 2 3 4

Что меня не бесит, так это то, что для создания $a3 мне нужно полностью распаковать $a1 и $a2. Для коротких массивов это не проблема, но по мере увеличения данных это означает, что все операции над массивами с псевдонимами - O(n), включая традиционно O(1) такие операции, как push или unshift.

Data::Alias может помочь, но он не работает с последними версиями Perl. Array::RefElem содержит оболочки вокруг примитивов API av_store и av_push, которые можно использовать для реализации этой функциональности. Так что-то вроде этого может работать:

sub alias_push (\@@) {
    if (eval {require Array::RefElem}) {
       &Array::RefElem::av_push($_[0], $_) for @_[1 .. $#_]
    } else {
       $_[0] = sub {\@_}->(@{$_[0]}, @_[1 .. $#_])
    }
}

Мне интересно знать, есть ли другие способы. Особенно, если есть другие способы использования только основных модулей.

1 Ответ

1 голос
/ 08 октября 2010

Является ли это одним из случаев, когда вам может понадобиться связанный список в Perl? Стив Лембарк рассказывает о различных случаях, когда людям следует пересматривать циклы прокрутки и развертывания.

Мне любопытно, почему ты так поступаешь. Не то чтобы я подозреваю что-то странное; Мне просто любопытно о проблеме.

...