subrutina llamar funciones comandos perl subroutine

llamar - funciones en perl



¿Cuándo debería usar & para llamar a una subrutina de Perl? (4)

El formulario & subrutina () deshabilita la comprobación del prototipo. Esto puede o no ser lo que quieres.

http://www.perl.com/doc/manual/html/pod/perlsub.html#Prototypes

Los prototipos le permiten especificar los números y tipos de sus argumentos de subrutina y hacer que se verifiquen en tiempo de compilación. Esto puede proporcionar asistencia de diagnóstico útil.

Los prototipos no se aplican a las llamadas a métodos, o llamadas hechas en el estilo pasado de moda usando el prefijo &.

El & es necesario para referenciar o desreferenciar una subrutina o referencia de código

p.ej

sub foo { # a subroutine } my $subref = /&foo; # take a reference to the subroutine &$subref(@args); # make a subroutine call using the reference. my $anon_func = sub { ... }; # anonymous code reference &$anon_func(); # called like this

Los prototipos tampoco son aplicables a las referencias de subrutinas.

La forma & subrutina también se usa en la llamada forma mágica de goto .

La expresión goto &subroutine reemplaza el contexto de llamada actual con una llamada a la subrutina nombrada, usando el valor actual de @_.

En esencia, puede cambiar completamente una llamada a una subrutina con una llamada al nombre. Esto se ve comúnmente en los bloques de AUTOLOAD, donde se puede realizar una llamada de subrutina diferida, quizás con alguna modificación a @_, pero se ve al programa por completo como si fuera una llamada al sub nombrado.

p.ej

sub AUTOLOAD { ... push @_, @extra_args; # add more arguments onto the parameter list goto &subroutine ; # change call another subroutine, as if we were never here }

}

Potencialmente, esto podría ser útil para la eliminación de llamadas de cola , supongo.

ver explicación detallada de esta técnica aquí

He oído que las personas no deberían usar & para llamar a los subs de Perl, es decir:

function($a,$b,...); # opposed to &function($a,$b,...);

Sé por una vez que la lista de argumentos se convierte en opcional, pero ¿en qué casos es apropiado usar & y los casos en los que no debería estar usándolo?

Además, ¿cómo funciona el aumento de rendimiento aquí al omitir el & ?


He leído los argumentos en contra de usar ''&'', pero casi siempre lo uso. Me ahorra mucho tiempo para no hacerlo. Paso una fracción muy grande de mi tiempo de codificación de Perl buscando qué partes del código llaman a una función en particular. Con un líder &, puedo buscar y encontrarlos al instante. Sin un encabezado &, obtengo la definición de la función, los comentarios y las declaraciones de depuración, generalmente triplicando la cantidad de código que tengo que inspeccionar para encontrar lo que estoy buscando.

Lo principal de no usar ''&'' es que le permite usar prototipos de funciones. Pero los prototipos de la función Perl pueden crear errores tan a menudo como lo previenen, ya que tomarán su lista de argumentos y la reinterpretarán en formas que usted no esperaría, de modo que su llamada de función ya no pasa los argumentos que literalmente dice que lo hace.


OMI, la única vez que hay alguna razón para usar & es si está obteniendo o llamando a un coderef, como:

sub foo() { print "hi/n"; } my $x = /&foo; &$x();

El momento principal en que puede usarlo que no debería usar en la mayoría de las circunstancias es cuando llama a un sub que tiene un prototipo que especifica un comportamiento de llamada no predeterminado. Lo que quiero decir con esto es que algunos prototipos permiten la reinterpretación de la lista de argumentos, por ejemplo la conversión de @array y las especificaciones de %hash a las referencias. Por lo tanto, el submarino esperará que se produzcan esas reinterpretaciones y, a menos que vaya a cualquier longitud que sea necesaria para imitarlas a mano, el submarinista obtendrá entradas muy diferentes de las que espera.

Creo que la mayoría de la gente trata de decirte que todavía escribes en estilo Perl 4, y ahora tenemos una cosa mucho más limpia y bonita llamada Perl 5.

En cuanto al rendimiento, hay varias formas en que Perl optimiza las sub llamadas que & derrotas, con una de las principales siendo el subrayado de las constantes.

También hay una circunstancia en la que usar & proporciona un beneficio de rendimiento: si reenvía una foo(@_) con foo(@_) . Usar &foo es infinitesimalmente más rápido que foo(@_) . No lo recomendaría, a menos que haya encontrado definitivamente mediante el perfil que necesita esa micro-optimización.


Soy un abusador frecuente de & , pero sobre todo porque estoy haciendo cosas raras en la interfaz. Si no necesita una de estas situaciones, no use el & . La mayoría de estos son solo para acceder a una definición de subrutina, no para llamar a una subrutina. Todo está en perlsub .

  1. Tomando una referencia a una subrutina nombrada. Esta es probablemente la única situación común para la mayoría de los Perlers:

    my $sub = /&foo;

  2. Del mismo modo, asignar a un typeglob, que le permite llamar a la subrutina con un nombre diferente:

    *bar = /&foo;

  3. Comprobando que se define una subrutina, como lo haría en suites de prueba:

    if( defined &foo ) { ... }

  4. Eliminar una definición de subrutina, que no debería ser común:

    undef &foo;

  5. Proporcionar una subrutina de despachador cuyo único trabajo es elegir la subrutina correcta para llamar. Esta es la única situación que uso & para llamar a una subrutina, y cuando espero llamar al despachador muchas, muchas veces y necesito exprimir un poco el rendimiento de la operación:

    sub figure_it_out_for_me { # all of these re-use the current @_ if( ...some condition... ) { &foo } elsif( ...some other... ) { &bar } else { &default } }

  6. Para saltar a otra subrutina utilizando la pila de argumentos actual (y reemplazar la subrutina actual en la pila de llamadas), una operación de liberación en la distribución, especialmente en AUTOLOAD :

    goto ⊂

  7. Llame a una subrutina que haya nombrado después de un Perl incorporado. El & siempre te da el definido por el usuario. Es por eso que lo enseñamos en Learning Perl . En realidad, no desea hacerlo normalmente, pero es una de las características de & .

Hay algunos lugares donde puedes usarlos, pero hay mejores maneras:

  1. Llamar a una subrutina con el mismo nombre que Perl incorporado. Simplemente no tiene subrutinas con el mismo nombre que un Perl incorporado. Compruebe perlfunc para ver la lista de nombres incorporados que no debe usar.

  2. Para deshabilitar prototipos. Si no sabes lo que eso significa o por qué lo querrías, no uses el & . Es posible que algún código de magia negra lo necesite, pero en esos casos probablemente sepa lo que está haciendo.

  3. Para eliminar referencia y ejecutar una referencia de subrutina. Solo usa la notación -> .