usar subrutina sintaxis programacion llamar guia ejemplos desde completo como comandos cero aprender perl

subrutina - perl pdf



¿Cómo puedo llamar elegantemente a una subrutina Perl cuyo nombre se mantiene en una variable? (12)

¿Huh? Puedes simplemente decir

$action->()

Ejemplo:

sub f { return 11 } $action = ''f''; print $action->(); $ perl subfromscalar.pl 11

Construcciones como

''f''->() # equivalent to &f()

Además trabajo.

Guardo el nombre de la subrutina que quiero llamar en tiempo de ejecución en una variable llamada $ action. Luego uso esto para llamar a ese sub en el momento correcto:

&{/&{$action}}();

Funciona bien. Lo único que no me gusta es que sea feo y cada vez que lo hago, me siento en deuda de agregar un comentario para el próximo desarrollador:

# call the sub by the name of $action

¿Alguien sabe una manera más bonita de hacer esto?

ACTUALIZACIÓN: La idea aquí era evitar tener que mantener una tabla de envío cada vez que agregué un nuevo sub llamable, ya que soy el único desarrollador, no me preocupan otros programadores que sigan o no sigan las ''reglas''. Sacrificando un poco de seguridad para mi conveniencia. En cambio, mi módulo de despacho verificaría $ action para asegurarme de que 1) es el nombre de una subrutina definida y no un código malicioso para ejecutar con eval, y 2) que no se ejecutará sub-precedido por un guión bajo, que sería marcados como subs internos solamente por esta convención de nomenclatura.

¿Alguna idea sobre este enfoque? Las subrutinas incluidas en la lista blanca en la tabla de envío es algo que siempre olvidaré, y mis clientes preferirían que yo me equivocara del lado de "funciona" que "es muy seguro". (tiempo muy limitado para desarrollar aplicaciones)

ACTUALIZACIÓN FINAL: creo que he decidido en una mesa de despacho después de todo. Aunque me gustaría saber si alguien que lee esta pregunta alguna vez intentó eliminar una y cómo lo hicieron, debo inclinarme ante la sabiduría colectiva aquí. Gracias a todos, muchas excelentes respuestas.


Cada paquete en Perl ya es una tabla hash. Puede agregar elementos y hacer referencia a ellos mediante las operaciones hash normales. En general, no es necesario duplicar la funcionalidad mediante una tabla hash adicional.

#! /usr/bin/perl -T use strict; use warnings; my $tag = ''HTML''; *::->{$tag} = sub { print ''<html>'', @_, ''</html>'', "/n" }; HTML("body1"); *::->{$tag}("body2");

El código se imprime:

<html>body1</html> <html>body2</html>

Si necesita un espacio de nombre independiente, puede definir un paquete dedicado.

Ver perlmod para más información.


En lugar de almacenar nombres de subrutinas en una variable y llamarlos, una mejor forma de hacerlo es usar un hash de referencias de subrutinas (también conocida como tabla de despacho ).

my %actions = ( foo => /&foo, bar => /&bar, baz => sub { print ''baz!'' } ... );

Entonces puedes llamar a la persona correcta fácilmente:

$actions{$action}->();

También puede agregar algunas comprobaciones para asegurarse de que $action sea ​​una clave válida en el hash, y así sucesivamente.

En general, debe evitar referencias simbólicas (lo que está haciendo ahora) ya que causan todo tipo de problemas. Además, el uso de referencias de subrutinas reales funcionará con el encendido strict .


Just &$action() , pero por lo general es mejor utilizar los códigos de barras desde el principio, o usar un hash de despachador. Por ejemplo:

my $disp = {foo => /&some_sub, bar => /&some_other_sub }; $disp->{''foo''}->();


Lo hice de esta manera:

@func = qw(cpu mem net disk); foreach my $item (@func){ $ret .= &$item(1); }


Lo más importante es: ¿por qué quieres usar la variable como nombre de la función? ¿Qué pasará si será ''eval''? ¿Hay una lista de funciones que se pueden usar? ¿O puede ser alguna función? Si existe una lista, ¿cuánto dura?

En general, la mejor manera de manejar estos casos es usar tablas de envío:

my %dispatch = ( ''addition'' => /&some_addition_function, ''multiplication'' => sub { $self->call_method( @_ ) }, );

Y luego solo:

$dispatch{ $your_variable }->( ''any'', ''args'' );


No estoy seguro de entender lo que quieres decir. (Creo que este es otro de un grupo reciente de preguntas sobre "¿Cómo puedo usar una variable como nombre de variable?", Pero tal vez no).

En cualquier caso, debería poder asignar una subrutina completa a una variable (como referencia), y luego llamarla directamente:

# create the $action variable - a reference to the subroutine my $action = /&preach_it; # later - perhaps much later - I call it $action->(); sub preach_it { print "Can I get an amen!/n" }


Si solo está en un programa, escriba una función que llame a una subrutina utilizando un nombre de variable y solo tenga que documentarla / disculparse una vez.


Usé esto: funciona para mí.

(/$action)->();

O puede usar ''do'', bastante similar a las publicaciones anteriores:

$p = do { /&$conn;}; $p->();


Ya sea uso

&{/&{$action}}();

O use eval para ejecutar la función:

eval("$action()");


Yo hago algo similar. Lo dividí en dos líneas para hacerlo un poco más identificable, pero no es mucho más bonito.

my $sub = /&{$action}; $sub->();

No sé de una manera más correcta o más bonita de hacerlo. Por lo que vale, tenemos un código de producción que hace lo que está haciendo, y funciona sin tener que deshabilitar el use strict .