Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I concatenate arrays of aliases in Perl?

Tags:

arrays

alias

perl

How do you concatenate arrays of aliases in Perl such that the resulting array also contains aliases?

The solution that I came up with is:

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

What I am not crazy about is that to create $a3 I have to completely unpack $a1 and $a2. For short arrays this isn't a problem, but as the data grows larger, it means that all array operations on aliased arrays are O(n), including traditionally O(1) operations like push or unshift.

Data::Alias could help, but it doesn't work with the latest versions of Perl. Array::RefElem contains wrappers around the api primitives av_store and av_push which can be used to implement this functionality. So something like this could work:

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

I am interested to know if there are any other ways. Particularly if there are any other ways using only the core modules.

like image 653
Eric Strom Avatar asked Oct 07 '10 18:10

Eric Strom


1 Answers

Is this one of the cases where you might want a linked list in Perl? Steve Lembark has a talk about the various cases where people should reconsider rolling and unrolling arrays.

I'm curious why you have to do things this way though. Not that I suspect anything odd; I'm just curious about the problem.

like image 75
brian d foy Avatar answered Oct 04 '22 23:10

brian d foy