This is a question about code that already works! I have lots subroutines that take multiple arrays as inputs, such as:
use 5.24.0;
use feature 'refaliasing';
no warnings "experimental::refaliasing";
my (@foo,@bar,@baz);
sub sumarr (\@\@);
# other code to load arrays
sub sumarr (\@\@)
{ my (@sum, @aa, @ab);
(\@aa,\@ab)=@_;
$sum[$_] = $aa[$_] + $ab[$_] for 0 .. $#aa;
return @sum;
}
...which I can call simply with
@baz = sumarr( @foo, @bar);
I haven't found any way to either replace the prototype with signatures, or at least augment the prototype with a signature for streamlining the argument list. Is there anything that does that yet?
Signatures unpack @_
into lexical variables which are scoped to within the function. Prototypes affect how calls to the function are parsed. So they do different things — you can't just replace one with the other. (You can write a function that has both though.)
An illustration of prototypes affecting parsing.
use strict;
use warnings;
use Data::Dumper;
my @a = ( 1 );
my @b = ( 2 );
myfunc( @a, @b );
sub myfunc (\@\@) {
print Dumper( @_ );
}
myfunc( @a, @b );
Notice that myfunc
gets called twice with the same arguments, yet produces different outputs. With use warnings
, Perl will at least warn you that you're doing something potentially weird.
As I mentioned, it is possible to declare both a signature and a prototype for the same function.
sub myfunc ( $A, $B ) :prototype(\@\@) {
print Dumper( @_ );
}
(Signatures are still experimental, and I believe that they did recently switch the order the signature and prototype are declared! A reason to beware experimental features.)
TLDR: you can't replace prototypes with signatures, because they're different things.