tags:

views:

86

answers:

1

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.

+1  A: 

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.

brian d foy
the linked list might be a good solution, it nicely sidesteps the `O(n)` issues. the application that I have in mind is to simulate Haskell like lazy behavior in Perl (mainly just because I think I can :), I'd like to eventually write something like this in Perl: `fibs = 0 : 1 : zipWith (+) fibs (tail fibs)` and part of that is managing argument lists that may contain values that have not been defined yet (but will be by the time they are needed)
Eric Strom
Oh, in that case, wait a year and use Perl 6. Lazy lists are one of the most attractive features for me. :)
brian d foy
@Eric, @brian, or maybe Perl 5.1x? (where x > 2 and x || 2)
Axeman