2009-06-24 3 views
1

Perl에서는 패키지가 알려진 경우 콜백 또는 코드 참조를 지정하는 것이 매우 간단합니다.Perl에서 콜백으로 사용할 메소드를 동적으로 선택하는 방법은 무엇입니까?

package Foo; 

sub foo { print "in foo" } 

# and then 
package main; 

sub baz { 
    my $code = shift; 
    $code->(); 
} 

baz(\&Foo::foo); 

그러면 in foo이 인쇄됩니다.

다음과 같이 매우 사소한 객체가 있다고 가정 해 보겠습니다.

package Foo; 

sub new { bless {}, shift } 
sub bar { print "in bar" } 
sub baz { print "in baz" } 

위의 방법 (\ & Package : Method)을 사용하여 메소드를 검색하고

package main; 
my $foo = Foo->new(); 
my $ref = \&Foo::bar; 
$foo->$ref(); 

하지만 때로는 (분명히, 종종) 당신은 명시 적 타입을 모른다. 말하자면 Foo, Bar, Baz가 있고 모두 blat 메서드가 있습니다. 패키지 대신 객체를 기반으로 적절한 메소드에 대한 참조를 얻으려고합니다. 그것에 대해 어떻게 생각하세요?

답변

7
my $ref = $obj->can('blat'); 

$ ref가 undef이면 객체가 손상 될 수 없습니다. $ ref가 undef가 아니라면 "$ obj -> $ ref (@args)"호출에 적합한 해당 함수에 대한 유효한 CODE 참조입니다.

+0

완벽. 감사! –

3

하자 방법 조회 당신을 위해 일을 할

my @objs = (Foo->new, Bar->new, Baz->new); 

my $method = "blat"; 
my $obj = $objs[rand @objs]; 
my $ref = $obj->can($method); 

if ($ref) { 
    print $ref->($obj), "\n"; 
} 
else { 
    print "$obj: no can $method\n"; 
} 

더 가까이는 다음과 같습니다

my $delegate = sub { $obj->$ref }; 
#   or sub { $obj->$method } 
print $delegate->(), "\n"; 
+1

는 도전할만한 방법입니다. UNIVERSAL perldoc 페이지는 UNIVERSAL :: can()을 직접하지 마십시오. 이렇게하면 무시가 작동하지 않습니다. 참조 http://perldoc.perl.org/UNIVERSAL.html –

+0

충분합니다. 수정 됨. –

관련 문제