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.
Creating a reference to a Perl array If we have an array called @names, we can create a reference to the array using a back-slash \ in-front of the variable: my $names_ref = \@names;. We use the _ref extension so it will stand out for us that we expect to have a reference in that scalar.
Array slicing can be done by passing multiple index values from the array whose values are to be accessed. These values are passed to the array name as the argument. Perl will access these values on the specified indices and perform the required action on these values. print "Extracted elements: " .
How to insert an element in the middle of an array in Perl? In this case we used splice to insert an element. Normally the second parameter (the offset) defines where to start the removal of elements, but in this case the third parameter - the number of elements - was 0 so splice has not removed any elements.
The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end ( end not included) where start and end represent the index of items in that array. The original array will not be modified.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With