2017-01-05 9 views

答えて

10

あなたのコードは、一般的に正しいですが、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. 
+1

私は男に魚を与えた、あなたは彼に魚の釣り方を教えた。 +1 – Zaid

+1

@Zaid oh、もう2つの答えがあります。私はまだそれらを見ませんでした。私はちょうどここに再び半分のブログ記事をハッキングして忙しかった...:D – simbabque

+0

HI simbabque。ありがとう。私はそれを知らなかった。私の場合、ユーザーは引数にサブルーチン名を指定するのではなく、良い情報を提供しています。 – Raj

7

あなたはコードを使用すると、を参照することをやりたいです。

@arrは、あなたが他の同じようにあなたのアレイを形成するために、これらのスカラを操作することができ、そのような

my $rc = sub { print "Anonymous subroutine\n" }; 

または

sub func { print "Named sub\n" } 
my $rc = \&func; 

としてスカラーが含まれてい

foreach my $sub (@arr) 
{ 
    $sub->(); 
} 

。しかし、ハッシュの値としてこれらを使用して、ディスパッチテーブルを作成する方が一般的で便利です。

perlrefを参照してください。this postも参考になります。

関連する問題