Как я могу вызвать подпрограмму, имя которой является значением в хэше, в Perl? - PullRequest
6 голосов
/ 01 октября 2010
$ 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.
$

Как правильно звонить route()?

Ответы [ 2 ]

13 голосов
/ 01 октября 2010

Вы пытаетесь использовать $ h {a} в качестве ссылки на символ. И это явно запрещено "использовать строгий". Если вы выключите строгий режим, то вы можете сделать это так:

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

Но лучший подход - сохранить "реальную" ссылку на подпрограмму в вашем хэше.

#!/usr/bin/perl

use strict;
use warnings;

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

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

$h{a}->();
3 голосов
/ 01 октября 2010

Вы должны разыменовать строку, содержащую имя подпрограммы как подпрограмму.Круглые скобки являются необязательными.

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

Поскольку имя вашей процедуры является хеш-значением, вы должны извлечь его из хеша.Кроме того, поскольку вы используете strict (что является хорошей практикой), вы должны локально отключать проверки.

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

Однако, как предположил Даворг в своем ответе, это будет лучше (с точки зрения производительности)непосредственно хранить ссылку на подпрограмму в вашем хэше вместо имени процедуры.

...