2010-03-20 19 views
5

He estado usando Perl desde hace algún tiempo, pero hoy me encontré con este código:

sub function1($$) 
{ 
    //snip 
} 

Lo que significa esto en Perl?

Respuesta

15

Es una función con prototype que toma dos argumentos escalares.


Existen argumentos sólidos para no utilizar los prototipos de Perl en general, como se señala en los comentarios a continuación. El argumento más fuerte es probablemente:

Hay una discusión en StackOverflow de 2008:

Hay una posible sustitución en el módulo MooseX::Method::Signatures.

+0

gracias !! casi lo descubro. Por cierto, ¿por qué es necesario, algún tipo de tipo y verificación de número en los parámetros, ¿verdad? – sud03r

+0

Perl no requiere prototipos; son completamente opcionales Sin embargo, al igual que en el código C, el suministro de prototipos puede evitar algunos errores que, de otro modo, no se detectarían. En general, en mi experiencia no se usan muy a menudo, en parte porque son una adición tardía al lenguaje, y en parte porque los programadores de Perl explotan (para bien, en general) la flexibilidad de los subs de Perl sin prototipos, y en parte porque a la gente no le gusta evitar errores automáticamente (parece preferir encontrarlos de la manera difícil). –

+3

Los prototipos no se usan en Perl moderno porque están rotos. ¿Qué tan roto? Aquí hay una pregunta reciente que ilustra solo uno de sus numerosos problemas: http://stackoverflow.com/questions/2485106/why-do-printf-and-sprintf-behave-differently Los prototipos no se utilizan para la comprobación de tipos, son pistas para el compilador y Perl forzarán * los argumentos de quien llama para que se ajusten al prototipo * incluso si están equivocados. – rjh

11

Como la otra respuesta menciona, $$ declara un prototipo. Lo que la otra respuesta no dice es para qué son los prototipos. No son para validación de entrada, son pistas para el analizador.

Imagine que tiene dos funciones declaradas como:

sub foo($) { ... } 
sub bar($$) { ... } 

Ahora, cuando se escribe algo ambigua, como:

foo bar 1, 2 

Perl sabe dónde poner los parens; bar toma dos args, por lo que consume los dos más cercanos a él. foo toma una arg, por lo que toma el resultado de la barra y los dos args:

foo(bar(1,2)) 

Otro ejemplo:

bar foo 2, 3 

Lo mismo se aplica; foo toma una arg, por lo que recibe el 2. Barra de dos argumentos, por lo que recibe foo(2) y 3:

bar(foo(2),3) 

Ésta es una parte muy importante de Perl, por lo que descartarlo como "nunca use" que está haciendo un mal servicio. Casi todas las funciones internas utilizan prototipos, por lo que, al comprender cómo funcionan en su propio código, puede obtener una mejor comprensión de cómo los utilizan los editores. Entonces puede evitar paréntesis innecesarios, lo que hace que el código sea más agradable.

Finalmente, un anti-patrón que voy a advertir contra:

package Class; 
sub new ($$) { bless $_[1] } 
sub method ($) { $_[0]->{whatever} } 

Cuando llame código como métodos (Class->method o $instance->method), la comprobación de prototipo es completamente sin sentido. Si su código solo puede invocarse como método, agregar un prototipo es incorrecto. He visto algunos módulos populares que hacen esto (hola, XML::Compile), pero está mal, así que no lo hagas.Si desea documentar el número de argumentos que pase, ¿qué tal:

sub foo { 
    my ($self, $a, $b) = @_; # $a and $b are the bars to fooify 
    .... 

o

use MooseX::Method::Signatures; 

method foo(Bar $a, Bar $b) { # fooify the bars 
    .... 

A diferencia de foo($$), estos son significativos y legible.

Cuestiones relacionadas