Tom Williams
Tom Williams

Reputation: 203

Signature without slurping

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?

Upvotes: 2

Views: 106

Answers (1)

tobyink
tobyink

Reputation: 13664

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.

Upvotes: 2

Related Questions