Podpis bez siorbania
To jest pytanie o kod, który już działa! Mam wiele podprogramów, które przyjmują wiele tablic jako dane wejściowe, takie jak:
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;
}
... z którym mogę po prostu zadzwonić
@baz = sumarr( @foo, @bar);
Nie znalazłem żadnego sposobu na zastąpienie prototypu podpisami lub przynajmniej rozszerzenie prototypu o sygnaturę w celu usprawnienia listy argumentów. Czy jest jeszcze coś, co to robi?
Odpowiedzi
Podpisy rozpakowywane są @_do zmiennych leksykalnych, których zakres obejmuje funkcję. Prototypy wpływają na sposób analizowania wywołań funkcji . Robią więc różne rzeczy - nie możesz po prostu zastąpić jednego drugim. (Możesz jednak napisać funkcję, która ma oba.)
Ilustracja prototypów wpływających na parsowanie.
use strict;
use warnings;
use Data::Dumper;
my @a = ( 1 );
my @b = ( 2 );
myfunc( @a, @b );
sub myfunc (\@\@) {
print Dumper( @_ );
}
myfunc( @a, @b );
Zauważ, że myfuncjest wywoływany dwukrotnie z tymi samymi argumentami, ale daje różne wyniki. Dzięki use warningsPerl przynajmniej ostrzeże Cię, że robisz coś potencjalnie dziwnego.
Jak wspomniałem, można zadeklarować zarówno podpis, jak i prototyp dla tej samej funkcji.
sub myfunc ( $A, $B ) :prototype(\@\@) {
print Dumper( @_ );
}
(Podpisy są nadal w fazie eksperymentalnej i wydaje mi się, że ostatnio zmienili kolejność deklarowania podpisu i prototypu! To powód, aby uważać na funkcje eksperymentalne).
TLDR: nie możesz zastąpić prototypów podpisami, ponieważ to różne rzeczy.