2009-01-17 3 views
4

J'essaie de comprendre comment itérer sur un ensemble de références de sous-programmes.Comment parcourir/déréférencer un tableau de références de sous-programmes en Perl?

Quel est le problème avec cette syntaxe?

use strict; 
use warnings; 

sub yell { print "Ahh!\n"; } 
sub kick { print "Boot!\n"; } 
sub scream { print "Eeek!\n"; } 

my @routines = (\&yell, \&kick, \&scream); 
foreach my $routine_ref (@routines) { 
    my &routine = &{$routine_ref}; 
    &routine; 
} 

Merci d'avance!

+0

Je ne sais pas. Qu'a dit l'interprète perl? –

+1

Vous itérez sur eux très bien. C'est les déréférencer c'est la vraie question. :) –

+0

@Jon: Il a dit que j'avais une erreur de syntaxe, mais je n'ai pas suggéré comment le corriger. @brian d foy: Bon point, je vais modifier le titre. :-) – cdleary

Répondre

10

Dans votre boucle foreach, ce qui suit est une erreur de syntaxe:

my &routine; 

votre variable $routine_ref a déjà une référence à la sous-routine, donc tout ce que vous besoin de faire à ce stade est l'appeler:

for my $routine_ref (@routines) { 
    &{$routine_ref}; 
} 

Comme toujours avec Perl, "Il y a plus d'une façon de le faire." Par exemple, si l'un de ces sous-routines ont pris des paramètres, vous pouvez les passer à l'intérieur des parenthèses comme ceci:

for my $routine_ref (@routines) { 
    $routine_ref->(); 
} 

Notez également que je l'ai utilisé for au lieu de foreach, qui est une meilleure pratice mis en avant par Damian Conway in Perl Best Practices.

+0

J'ai toujours préféré le dernier exemple, son comportement moins ambigu à moi. (+1) –

+0

Vous ne voulez probablement pas le déréférencer avec seulement le &. Sans les parenthèses, cela utilise la valeur actuelle de @_ comme liste d'arguments implicite, et ce n'est généralement jamais ce que vous voulez faire. –

+0

Bon point Brian. –

0

Essayez ceci:

use strict; 
use warnings; 

sub yell { print "Ahh!\n"; } 
sub kick { print "Boot!\n"; } 
sub scream { print "Eeek!\n"; } 

my @routines = (\&yell, \&kick, \&scream); 
foreach my $routine_ref (@routines) { 
    &$routine_ref(); 
} 
+1

& $ routine_ref l'appelle. Les parens ne font rien. – Axeman

4
foreach my $routine_ref (@routines) { 
     $routine_ref->(); 
} 
Questions connexes