Существует две стратегии: либо изучить таблицу символов для инициализации при создании, либо использовать AUTOLOAD и выполнить тестирование с помощью can
. AUTOLOAD может быть сложнее, так как вам приходится иметь дело со случаем, когда метод отсутствует:
sub AUTOLOAD {
my $self = shift;
my $method = $AUTOLOAD;
$method =~ s/.*://; # strip package name
if ( $self->{'result'}->can($method) ) {
return $self->{'result'}->$method(@_);
} else {
croak "Unknown method : $method";
}
}
Но трюк с таблицей символов хрупок, так как, если они используют наследование, вы не увидите унаследованные методы и без перехода на @ISA. (и даже если это не так - они могут начать использовать наследование в будущем, что приведет к поломке)
...
Как правило, когда вы пытаетесь скопировать интерфейс другого модуля, у вас есть случай наследования, поэтому вы можете спросить себя, каковы отношения между ::d
и ::e
:
a::b::c::d
является a::b::c::e
a::b::c::d
использует a::b::c::e
Если это отношение типа "отношения", оно обычно лучше подходит для наследования (хотя у вас могут быть обертки вокруг каждого из методов, и вам все равно придется пройти через все это упражнение). Если это отношение использует, скорее всего, вы не хотите наследовать от каждого последнего метода, который у них есть, и можете просто жестко закодировать список (хотя список может измениться, если обновленный класс обновится)
foreach my $method ( @list_of_methods_to_copy ) {
*{$method} = sub {
my $self = shift;
return $self->{'results'}->$method(@_);
}
}