私はすべてのサブルーチン名を含む配列を1つずつ持ち、1つずつ呼び出したいとします。変数名を使ってperlでサブルーチンを呼び出す方法
foreach $sub (@arr){
print "Calling $sub\n";
#---How to call $sub?----
&$sub; ## will not work
}
私はすべてのサブルーチン名を含む配列を1つずつ持ち、1つずつ呼び出したいとします。変数名を使ってperlでサブルーチンを呼び出す方法
foreach $sub (@arr){
print "Calling $sub\n";
#---How to call $sub?----
&$sub; ## will not work
}
あなたのコードは、一般的に正しいですが、Perlはあなたがコード、参考文献として変数コンテンツを使用できるようにするためにstrict 'refs'
をオフにする必要があります。
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
にユーザー入力が含まれている場合、これは大きな問題です。あなたのユーザーはコードを注入することができます。このことを考えてみましょう:
my @arr = qw/CORE::die/;
は、今、私たちは次のような出力が得られます。
Calling CORE::die
Died at /home/code/scratch.pl line 1492.
おっと。あなたはこれをしたくありません。 die
の例はそれほど悪くはありませんが、このように意図しない別のパッケージのコードを簡単に呼び出すことができます。
dispatch tableを作成する方がいいでしょう。 高等裁判所のPerlには、Mark Jason Dominusの人物に関する章があります。download for free on his websiteです。
基本的には、すべてのサブセクションをコード参照としてハッシュに入れてから、それらをループ内で呼び出すことを意味します。そうすれば、許可されているものを制御できます。
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.
あなたはコードを使用すると、を参照することをやりたいです。
@arr
は、あなたが他の同じようにあなたのアレイを形成するために、これらのスカラを操作することができ、そのような
my $rc = sub { print "Anonymous subroutine\n" };
または
sub func { print "Named sub\n" }
my $rc = \&func;
としてスカラーが含まれてい
foreach my $sub (@arr)
{
$sub->();
}
。しかし、ハッシュの値としてこれらを使用して、ディスパッチテーブルを作成する方が一般的で便利です。
'(\&$ name) - >(@ args)' – ikegami