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.