I am having trouble passing and reading arguments inside subroutine which is expected to have two arrays.
sub two_array_sum { # two_array_sum ( (1 2 3 4), (2, 4, 0, 1) ) -> (3, 6, 3, 5)
# I would like to use parameters @a and @b as simply as possible
}
# I would like to call two_array_sum here and pass two arrays, @c and @d
I have seen and tried several examples from the web, but none of them worked for me.
There are two ways you can do this:
But before I discuss these--if what you show in your question is about the extent of what you want to do--let me suggest List::MoreUtils::pairwise
So, where you would write this:
my @sum = two_array_sum( @a, @b )
You'd simply write this:
my @sum = pairwise { $a + $b } @a, @b;
This works like push
. (And just like push
it demands to have a @
sigil on something)
sub two_array_sub (\@\@) {
my ( $aref, $bref ) = @_;
...
}
That way when you do this
two_array_sub( @a, @b );
it works. Whereas normally it would just show up in your sub as one long list. They aren't for everybody as you'll see in my discussion below.
That's the way that everybody is showing you.
some_sub( \@a, \@b );
They're finicky. This won't work if you have refs:
two_array_sub( $arr_ref, $brr_ref );
You have to pass them like this:
two_array_sub( @$arr_ref, @$brr_ref );
However, because making "array expressions" gets really ugly quickly with arrays nested deep, I often avoid Perl's fussiness as you can overload the type of reference Perl will take by putting it in a "character class" construct. \[$@]
means that the reference can either be a scalar or array.
sub new_two_array_sub (\[$@]\[$@]) {
my $ref = shift;
my $arr = ref( $ref ) eq 'ARRAY' ? $ref : $$ref; # ref -> 'REF';
$ref = shift;
my $brr = ref( $ref ) eq 'ARRAY' ? $ref : $$ref;
...
}
So all these work:
new_two_array_sub( @a, $self->{a_level}{an_array} );
new_two_array_sub( $arr, @b );
new_two_array_sub( @a, @b );
new_two_array_sub( $arr, $self->{a_level}{an_array} );
However, Perl is still fussy about this... for some reason:
new_two_array_sub( \@a, $b );
OR
new_two_array_sub( $a, [ 1..3 ] );
Or any other "constructor" that still could be seen as a reference to an array. Fortunately, you can shut Perl up about that with the old Perl 4 &
&new_two_array_sub( \@a, [ 1..3 ] );
Then the mux-ing code in the sub takes care of handling two array references.