Pregunta

En otra pila & nbsp; Pregunta de desbordamiento Leon Timmermans afirmó:

  

Te aconsejaría que no uses prototipos. Tienen sus usos, pero no para la mayoría de los casos y definitivamente no en este caso.

¿Por qué podría ser esto cierto (o no)? Casi siempre proporciono prototipos para mis funciones de Perl, y nunca antes había visto a nadie decir nada malo sobre su uso.

¿Fue útil?

Solución

Los prototipos no son malos si se usan correctamente. La dificultad es que los prototipos de Perl no funcionan de la manera que la gente suele esperar. Las personas con experiencia en otros lenguajes de programación tienden a esperar que los prototipos proporcionen un mecanismo para verificar que las llamadas a funciones sean correctas: es decir, que tengan el número y el tipo correctos de argumentos. Los prototipos de Perl no son adecuados para esta tarea. Es el mal uso lo que es malo. Los prototipos de Perl tienen un propósito singular y muy diferente:

Los prototipos le permiten definir funciones que se comportan como funciones integradas.

  • Los paréntesis son opcionales.
  • El contexto se impone a los argumentos.

Por ejemplo, podría definir una función como esta:

sub mypush(\@@) { ... }

y llámalo como

mypush @array, 1, 2, 3;

sin necesidad de escribir el \ para tomar una referencia a la matriz.

En pocas palabras, los prototipos te permiten crear tu propio azúcar sintáctico. Por ejemplo, el marco Moose los usa para emular una sintaxis OO más típica.

Esto es muy útil pero los prototipos son muy limitados:

  • Deben ser visibles en tiempo de compilación.
  • Se pueden omitir.
  • Propagar el contexto a argumentos puede causar un comportamiento inesperado.
  • Pueden dificultar la invocación de funciones que no sean forma estrictamente prescrita.

Ver Prototipos en perlsub para todos los detalles sangrientos.

Otros consejos

El problema es que los prototipos de funciones de Perl no hacen lo que la gente piensa que hacen. Su propósito es permitirle escribir funciones que se analizarán como las funciones integradas de Perl.

En primer lugar, las llamadas a métodos ignoran completamente los prototipos. Si está haciendo programación OO, no importa qué prototipo tengan sus métodos. (Por lo tanto, no deberían tener ningún prototipo).

Segundo, los prototipos no se aplican estrictamente. Si llama a una subrutina con & amp; function (...) , el prototipo se ignora. Por lo tanto, realmente no proporcionan ningún tipo de seguridad.

Tercero, son espeluznantes de acción a distancia. (Especialmente el prototipo $ , que hace que el parámetro correspondiente se evalúe en contexto escalar, en lugar del contexto de lista predeterminado).

En particular, dificultan el paso de parámetros de las matrices. Por ejemplo:

my @array = qw(a b c);

foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);

sub foo ($;$) { print "@_\n" }

foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);

impresiones:

a b c
a b
a b c
3
b
a b c

junto con 3 advertencias sobre main :: foo () llamado demasiado temprano para verificar el prototipo (si las advertencias están habilitadas). El problema es que una matriz (o segmento de matriz) evaluada en contexto escalar devuelve la longitud de la matriz.

Si necesita escribir una función que actúe como una función incorporada, use un prototipo. De lo contrario, no use prototipos.

Nota: Perl 6 tendrá prototipos completamente renovados y muy útiles. Esta respuesta se aplica solo a Perl 5.

Estoy de acuerdo con los dos carteles anteriores. En general, debe evitarse el uso de $ . Los prototipos solo son útiles cuando se usan argumentos de bloque ( & amp; ), globos ( * ) o prototipos de referencia ( \ @ , \ $ , \% , \ * )

Algunas personas, mirando un prototipo de subrutina Perl, piensan que significa algo que no significa:

sub some_sub ($) { ... }

Para Perl, eso significa que el analizador espera dos argumentos. Es la forma en que Perl le permite crear subrutinas que se comportan como incorporadas, todas las cuales saben qué esperar del código siguiente. Puede leer acerca de los prototipos en perlsub

Sin leer la documentación, la gente adivina que los prototipos se refieren a la comprobación de argumentos en tiempo de ejecución o algo similar que han visto en otros idiomas. Como con la mayoría de las cosas que la gente adivina sobre Perl, resultan estar equivocadas.

Sin embargo, comenzando con Perl v5.20, Perl tiene una característica, experimental mientras escribo esto, que ofrece algo más parecido a lo que los usuarios esperan y qué. Las firmas de subrutinas ejecutan el conteo de argumentos en tiempo de ejecución, variable asignación y configuración predeterminada:

use v5.20;
use feature qw(signatures);
no warnings qw(experimental::signatures);

animals( 'Buster', 'Nikki', 'Godzilla' );

sub animals ($cat, $dog, $lizard = 'Default reptile') { 
    say "The cat is $cat";
    say "The dog is $dog";
    say "The lizard is $lizard";
    }

Esta es la característica que probablemente desee si está considerando prototipos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top