2010-10-01 2 views
6
$ cat test.pl 
use strict; 
use warnings; 

sub route { 
    print "hello, world!"; 
} 

my %h; 
$h{'a'} = 'route'; 

print "1\n"; 
$h{a}; 

print "2\n"; 
$h{a}(); 

print "3\n"; 
"$h{a}".(); 
$ perl test.pl 
Useless use of hash element in void context at test.pl line 12. 
Useless use of concatenation (.) or string in void context at test.pl line 18. 
1 
2 
Can't use string ("route") as a subroutine ref while "strict refs" in use at test.pl line 15. 
$ 

Quelle est la bonne façon d'appeler route()?Comment appeler un sous-programme dont le nom est une valeur dans un hachage, en Perl?

+0

duplication possible de [Comment appeler un nom de fonction stocké dans un hachage en Perl?] (Http://stackoverflow.com/questions/1836178/how-do-i-call-a-function-name -that-is-stored-in-a-hash-in-perl) – Ether

Répondre

13

Vous essayez d'utiliser $ h {a} comme référence de symbole. Et cela est explicitement interdit par "use strict". Si vous désactivez le mode strict, alors vous pouvez le faire comme ceci:

no strict; 
&{$h{a}}; 

Mais la meilleure approche est de stocker une référence « réelle » à la sous-routine dans votre hachage.

#!/usr/bin/perl 

use strict; 
use warnings; 

sub route { 
    print "hello, world!"; 
} 

my %h; 
$h{a} = \&route; 

$h{a}->(); 
+3

Bien que je sois complètement d'accord avec la suggestion de davorg d'utiliser des références de code, je tiens également à souligner la fonction 'can' de perl. Étant donné le nom du paquet dans lequel une fonction se trouve et le nom de la fonction elle-même, elle peut récupérer la référence de code pour cette fonction en utilisant $ package-> can ($ function) ', sans avoir à désactiver les références strictes. – rafl

+2

'pas de 'refs' strict est suffisant. – dolmen

3

Vous devez déréférencer la chaîne contenant le nom de la routine en tant que sous-élément. Les parenthèses sont facultatives. Comme votre nom de routine est une valeur de hachage, vous devez l'extraire du hachage. De même que vous utilisez strict (ce qui est une bonne pratique), vous devez désactiver localement les contrôles.

{ 
    no strict 'refs'; 
    &{$h{a}}; 
} 

Cependant, comme davorg a suggéré dans sa réponse, il serait préférable (sage-performance) pour stocker directement une référence au sous dans votre hachage, au lieu du nom de routine.

Questions connexes