2010-10-01 7 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. 
$ 

Jaki jest właściwy sposób połączenia pod numer route()?Jak mogę wywołać podprogram, którego nazwa jest wartością w mieszaniu, w Perlu?

+0

możliwy duplikat [Jak wywołać nazwę funkcji zapisaną w haszowaniu w Perlu?] (Http://stackoverflow.com/questions/1836178/how-do-i-call-a-function-name -to-jest-przechowywany-w-a-hash-in-perlu) – Ether

Odpowiedz

13

Próbujesz użyć $ h {a} jako odniesienia do symboli. I to jest wyraźnie zabronione przez "use strict". Jeśli wyłączysz tryb ścisły, to można to zrobić tak:

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

Ale najlepszym rozwiązaniem jest przechowywanie „prawdziwy” odniesienie do podprogramu w hash.

#!/usr/bin/perl 

use strict; 
use warnings; 

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

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

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

Chociaż całkowicie zgadzam się z sugestią Davorga dotyczącą używania odnośników do kodu, chcę również wskazać funkcję "puszki" perla. Biorąc pod uwagę nazwę pakietu, funkcję i nazwę funkcji, może ona pobrać odwołanie do kodu dla tej funkcji za pomocą '$ package-> can (funkcja $)', bez konieczności wyłączania ścisłego refs. – rafl

+2

"brak ścisłego" refs "wystarczy. – dolmen

3

Musisz wyłuskać łańcuch zawierający nazwę rutynową jako sub. Nawias są opcjonalne.

my $name = 'route'; 
&{$name}; 

Ponieważ nazwa rutynowa jest wartością mieszającą, należy ją wyodrębnić z wartości mieszania. Również podczas korzystania z strict (co jest dobrą praktyką), trzeba lokalnie wyłączyć kontrole.

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

Jednakże, jak davorg zasugerował w swojej odpowiedzi, że byłoby lepiej (performance-wise) bezpośrednio do przechowywania odwołanie do sub w swoim hash zamiast rutynowego nazwy.

Powiązane problemy