gpt4 book ai didi

perl - 如何使用变量名在perl中调用子程序

转载 作者:行者123 更新时间:2023-12-04 16:28:43 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





How can I elegantly call a Perl subroutine whose name is held in a variable?

(12 个回答)


5年前关闭。




假设我有一个包含所有子例程名称的数组,我想一一调用。

foreach $sub (@arr){
print "Calling $sub\n";
#---How to call $sub?----
&$sub; ## will not work
}

最佳答案

您的代码总体上是正确的,但您需要关闭 strict 'refs' 使 Perl 允许您使用变量内容作为代码引用。

use strict;
use warnings;

sub foo { print "foo" }
sub bar { print "bar" }

my @arr = qw/foo bar/;
foreach my $sub (@arr) {
no strict 'refs';
print "Calling $sub\n";

&$sub();
}

这里的输出是:
Calling foo
fooCalling bar
bar

我还添加了括号 ()通话后。这样我们就不会向 %$sub 传递任何参数。 .如果我们不这样做, @_将使用当前子程序的参数列表。

但是,您可能不应该这样做。特别是如果 @arr包含用户输入,这是一个大问题。您的用户可以注入(inject)代码。考虑一下:
my @arr = qw/CORE::die/;

现在我们得到以下输出:
Calling CORE::die
Died at /home/code/scratch.pl line 1492.

哎呀。你不想这样做。 die例子不是很糟糕,但是像这样你可以很容易地调用一些不同的包中的代码,而不是预期的。

制作 dispatch table 可能会更好. Mark Jason Dominus 的高阶 Perl 有一整章,你可以 download for free on his website .

这基本上意味着您将所有 subs 作为代码引用放入哈希中,然后在循环中调用它们。这样你就可以控制哪些是允许的。
use strict;
use warnings;

sub baz { print "baz" }

my %dispatch = (
foo => sub { print "foo" },
bar => sub { print "bar" },
baz => \&baz,
);

my @arr = qw/foo bar baz wrong_entry/;
foreach my $sub ( @arr ) {
die "$sub is not allowed"
unless exists $dispatch{$sub};

$dispatch{$sub}->();
}

这输出:
foobarbaz
wrong_entry is not allowed at /home/code/scratch.pl line 1494.

关于perl - 如何使用变量名在perl中调用子程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41481745/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com