2017-01-05 5 views

답변

10

코드는 일반적으로 정확하지만 당신은 펄 당신이 코드 심판 등의 변수 컨텐츠를 사용할 수 있도록하기 위해 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 (마크 제이슨 도미누스)에 관한 내용은 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

@ 아아, 두 가지 답변이 더 있습니다. 나는 아직 그들을 보지 못했다.나는 여기에 다시 블로그 게시물 절반을 해킹하는 중 바빴다. : 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도 도움이 될 수 있습니다.