2009-09-28 12 views
11

Todos deberíamos estar familiarizados con los problemas relacionados con prototypes en Perl. Aquí están los dos biggies:¿De cuántas maneras puede llamar a una subrutina e ignorar su prototipo en Perl?

  • no funcionan como prototipos en otros idiomas, por lo que la gente no los entiende.
  • no se aplican a todas las formas de llamar a una subrutina.

El segundo artículo es el que tengo curiosidad por el momento.

Conozco dos maneras de subvertir/evitar/ignore la aplicación de prototipo cuando se llama a una subrutina:

  • ir al sub como método. Foo->subroutine_name();
  • Llame al submarino con un sigil principal &. &subroutine_name();

¿Hay algún otro caso interesante que me haya perdido?

udpate:

@ Brian d Foy, yo no quiero particularmente para evadir prototipos, pero se preguntó "cuántas maneras hay para hacerlo?" Hago esta pregunta por curiosidad.

@jrockway, estoy de acuerdo contigo, y creo que tienes más explícita y más concisamente descrito mi primer punto con respecto a los problemas con los prototipos, que la gente los malinterpreta. Quizás el problema radique en las expectativas del programador y no en la característica. Pero esa es realmente una pregunta filosófica del tipo que no quiero tener.

+8

Esto no es un "problema". Los prototipos son pistas para el lexer, no un marco de validación de datos. Comprende eso y no tendrás problemas. – jrockway

+1

Referencia cruzada a la pregunta donde se trata esto con más detalle: http://stackoverflow.com/questions/297034/why-are-perl-function-prototypes-bad – Ether

+0

¿Por qué intenta ignorar un prototipo? –

Respuesta

11

Llámalo a través de una referencia de subrutina.

sub foo($) { print "arg is $_[0]\n" } 
my $sub = \&foo; 
$sub->(); 

Llame antes de Perl ha visto el prototipo (importante porque Perl no hace que se declara submarinos antes de su uso):

foo(); 
sub foo($) { print "arg is $_[0]\n" } 
+3

Curiosamente, 'print prototype ($ sub)," \ n ";' todavía imprime "$" (el prototipo correcto). –

+1

El segundo da una advertencia: main :: foo() llamó demasiado temprano para verificar el prototipo ... – oylenshpeegul

+0

Parece que cualquier llamada que se determine en el tiempo de ejecución los pasos alrededor de ellos.Esto tiene sentido ya que se procesan en tiempo de compilación. – daotoad

3

Utilizando la sintaxis goto &name.

3

Tipo-glob.

sub foo($) { print "arg is $_[0]\n" } 
*foo{CODE}() 

Además, considere Bar-> foo() reescrito en notación indirecta:

foo Bar 

más? Vamos, tráelo.

Cuestiones relacionadas