Firma senza slurping
Questa è una domanda sul codice che già funziona! Ho molte subroutine che accettano più array come input, come ad esempio:
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;
}
... che posso chiamare semplicemente con
@baz = sumarr( @foo, @bar);
Non ho trovato alcun modo per sostituire il prototipo con le firme, o almeno aumentare il prototipo con una firma per snellire l'elenco degli argomenti. C'è ancora qualcosa che lo fa?
Risposte
Le firme vengono decompresse @_in variabili lessicali che hanno come ambito la funzione. I prototipi influenzano il modo in cui vengono analizzate le chiamate alla funzione . Quindi fanno cose diverse: non puoi semplicemente sostituire l'uno con l'altro. (Puoi scrivere una funzione che ha entrambi però.)
Un'illustrazione dei prototipi che influenzano l'analisi.
use strict;
use warnings;
use Data::Dumper;
my @a = ( 1 );
my @b = ( 2 );
myfunc( @a, @b );
sub myfunc (\@\@) {
print Dumper( @_ );
}
myfunc( @a, @b );
Si noti che myfuncviene chiamato due volte con gli stessi argomenti, ma produce output diversi. Con use warnings, Perl ti avverte almeno che stai facendo qualcosa di potenzialmente strano.
Come ho già detto, è possibile dichiarare sia una firma che un prototipo per la stessa funzione.
sub myfunc ( $A, $B ) :prototype(\@\@) {
print Dumper( @_ );
}
(Le firme sono ancora sperimentali e credo che di recente abbiano cambiato l'ordine di dichiarazione della firma e del prototipo! Un motivo per fare attenzione alle funzionalità sperimentali.)
TLDR: non puoi sostituire i prototipi con le firme, perché sono cose diverse.