Firma sin sorber

Sep 08 2020

¡Esta es una pregunta sobre el código que ya funciona! Tengo muchas subrutinas que toman múltiples matrices como entradas, como:

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;
    }

... que puedo llamar simplemente con

@baz = sumarr( @foo, @bar);

No he encontrado ninguna forma de reemplazar el prototipo con firmas, o al menos aumentar el prototipo con una firma para simplificar la lista de argumentos. ¿Hay algo que haga eso todavía?

Respuestas

2 tobyink Sep 09 2020 at 00:04

Las firmas se descomponen @_en variables léxicas que tienen un alcance dentro de la función. Los prototipos afectan la forma en que se analizan las llamadas a la función . Entonces hacen cosas diferentes, no puedes simplemente reemplazar uno por otro. (Sin embargo, puede escribir una función que tenga ambos).

Una ilustración de prototipos que afectan al análisis.

use strict;
use warnings;
use Data::Dumper;

my @a = ( 1 );
my @b = ( 2 );

myfunc( @a, @b );

sub myfunc (\@\@) {
    print Dumper( @_ );
}

myfunc( @a, @b );

Tenga en cuenta que myfuncse llama dos veces con los mismos argumentos, pero produce diferentes salidas. Con use warnings, Perl al menos le advertirá que está haciendo algo potencialmente extraño.

Como mencioné, es posible declarar tanto una firma como un prototipo para la misma función.

sub myfunc ( $A, $B ) :prototype(\@\@) {
    print Dumper( @_ );
}

(¡Las firmas aún son experimentales y creo que recientemente cambiaron el orden en que se declaran la firma y el prototipo! Una razón para tener cuidado con las características experimentales).

TLDR: no se pueden reemplazar prototipos con firmas, porque son cosas diferentes.