2009-09-28 4 views
11

Nous devrions tous être familiers avec les problèmes liés à prototypes dans Perl. Voici les deux biggies:De combien de façons pouvez-vous appeler un sous-programme et ignorer son prototype en Perl?

  • ils ne fonctionnent pas comme des prototypes dans d'autres langues, donc les gens les comprennent mal.
  • ils ne s'appliquent pas à toutes les façons d'appeler un sous-programme.

Le deuxième article est celui pour lequel je suis curieux en ce moment.

Je connais deux façons de subvertir/contourner/ignorer l'application prototype lors de l'appel d'un sous-programme:

  • appel sous comme méthode. Foo->subroutine_name();
  • Appelez le sous-marin avec un sigil & principal. &subroutine_name();

Y a-t-il d'autres cas intéressants que j'ai manqués?

udpate:

d foy @ Brian, je ne veux pas particulièrement pour échapper à des prototypes, mais je me suis demandé « combien de façons sont là pour le faire? » Je pose cette question par curiosité. @jrockway, je suis d'accord avec vous, et je crois que vous avez décrit de façon plus explicite et plus concise mon premier point concernant les problèmes avec les prototypes, que les gens ne comprennent pas bien. Peut-être que le problème réside dans les attentes des programmeurs et non dans la fonctionnalité. Mais c'est vraiment une question philosophique du genre que je ne veux pas avoir.

+8

Ceci n'est pas un "problème". Les prototypes sont des indices pour le lexer, pas un cadre de validation de données. Comprenez cela et vous n'aurez pas de problèmes. – jrockway

+1

Renvoi à la question où cela est discuté plus en détail: http://stackoverflow.com/questions/297034/why-are-perl-function-prototypes-bad – Ether

+0

Pourquoi essayez-vous d'ignorer un prototype? –

Répondre

11

Appelez-le via une référence de sous-programme.

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

Appelez avant Perl a vu le prototype (important parce que Perl ne vous fait pas déclarer les sous-marins avant utilisation):

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

Fait intéressant, 'print prototype ($ sub)," \ n ";' affiche toujours "$" (le prototype correct). –

+1

La seconde donne un avertissement: main :: foo() appelé trop tôt pour vérifier le prototype ... – oylenshpeegul

+0

Il semble que tout appel déterminé à l'exécution les contourne.Cela a du sens car ils sont traités au moment de la compilation. – daotoad

3

En utilisant la syntaxe goto &name.

3

Type-glob.

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

Aussi, pensez à Bar-> foo() réécrite en notation indirecte:

foo Bar 

plus? Allez, amenez-le.

Questions connexes