【问题标题】:How can I call a subroutine whose name is a value in a hash, in Perl?如何在 Perl 中调用名称是哈希值的子例程?
【发布时间】:2023-03-13 19:50:01
【问题描述】:
$ 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()的正确方法是什么?

【问题讨论】:

标签: perl hash subroutine


【解决方案1】:

您正在尝试使用 $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}->();

【讨论】:

  • 虽然我完全同意 davorg 关于使用代码引用的建议,但我还想指出 perl 的 can 功能。给定函数所在包的名称和函数名称本身,它可以使用$package->can($function) 检索该函数的代码引用,而无需关闭严格的引用。
  • no strict 'refs' 就够了。
【解决方案2】:

您必须取消引用包含例程名称的字符串作为子项。括号是可选的。

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

由于您的例程名称是一个哈希值,您必须从哈希中提取它。此外,当您使用 strict(这是一个很好的做法)时,您必须在本地禁用检查。

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

但是,正如 davorg 在他的回答中所建议的那样,最好(在性能方面)直接在您的哈希中存储对 sub 的引用,而不是例程名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2013-02-06
    • 2012-04-25
    • 2012-06-22
    • 2011-02-01
    • 2014-07-02
    • 2010-11-12
    相关资源
    最近更新 更多