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
방법. 패키지 대신 객체를 기반으로 적절한 방법에 대한 참조를 얻으려고합니다. 그것에 대해 어떻게 하시겠습니까?
해결책
my $ref = $obj->can('blat');
$ ref가 undef 인 경우, 객체가 날려 버릴 수 없습니다. $ ref가 undef가 아닌 경우, "$ obj-> $ ref (@args)"를 호출하는 데 적합한 해당 함수에 대한 유효한 코드 참조입니다.
다른 팁
메소드 조회가 당신을 위해 작동하도록하십시오.
$ cat try
#! /usr/bin/perl
use warnings;
use strict;
package Foo;
sub new { bless {} => shift }
sub blat { "Foo blat" }
package Bar;
sub new { bless {} => shift }
sub blat { "Bar blat" }
package Baz;
sub new { bless {} => shift }
sub blat { "Baz blat" }
package main;
my $method = "blat";
foreach my $obj (Foo->new, Bar->new, Baz->new) {
print $obj->$method, "\n";
}
$ ./try
Foo blat
Bar blat
Baz blat
참조가 필요한 경우 Perl은 대의원이 없지만 가까이 갈 수 있음을 명심하십시오.
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";
제휴하지 않습니다 StackOverflow