Reputation: 40142
How would you take a reference to an array slice such that when you modify elements of the slice reference, the original array is modified?
The following code works due to @_
aliasing magic, but seems like a bit of a hack to me:
my @a = 1 .. 10;
my $b = sub{\@_}->(@a[2..7]);
@$b[0, -1] = qw/ < > /;
print "@a\n";
# 1 2 < 4 5 6 7 > 9 10
Anyone have a better / faster way?
Edit: the code example above is simply to illustrate the relationship required between @a and $b, it in no way reflects the way this functionality will be used in production code.
Upvotes: 7
Views: 1652
Reputation: 98398
That's how you do it, yes. Think about it for a bit and it's not such a hack; it is simply using Perl's feature for assembling arbitrary lvalues into an array and then taking a reference to it.
You can even use it to defer creation of hash values:
$ perl -wle'my %foo; my $foo = sub{\@_}->($foo{bar}, $foo{baz}); print "before: ", keys %foo; $foo->[1] = "quux"; print "after: ", keys %foo'
before:
after: baz
Upvotes: 3
Reputation: 118128
Data::Alias seems to be able to do what you want:
#!/usr/bin/perl
use strict; use warnings;
use Data::Alias;
my @x = 1 .. 10;
print "@x\n";
my $y = alias [ @x[2 ..7] ];
@$y[0, -1] = qw/ < > /;
print "@x\n";
Output:
1 2 3 4 5 6 7 8 9 10 1 2 < 4 5 6 7 > 9 10
Upvotes: 5