Благодаря стандартному Perl. , , Метод comes_from
!
Вам не нужно загружать какой-либо специальный инструмент или модуль, не говоря уже о какой-то гигантской среде IDE, потому что ваша недокументированная структура классов стала слишком сложной для простых людей, которых когда-либо понимали без неуклюжих IDE.
Почему нет?Простой: Стандартный Perl содержит все, что вам нужно, чтобы получить ответ, который вы ищете. Самый простой способ узнать, где что-то происходит от заключается в использовании очень полезный comes_from
метода:
$origin = $self->comes_from("mystery");
$secret_origin = $self->comes_from("another_mystery");
$birthplace = Some::Class->comes_from("method_name");
Это возвратит оригинальное имя подпрограммы, которые этот метод позволит решить к. Как вы видите, comes_from
работает как метод объекта, так и метод класса, как и can
и isa
.
Обратите внимание, что когда я говорю имя подпрограммы, которую он разрешает, я имею в виду, где эта подпрограмма была первоначально создана, перед каким-либо импортом или наследованием. Например, этот код:
use v5.10.1;
use Path::Router;
my($what, $method) = qw(Path::Router dump);
say "$what->$method is really ", $what->comes_from($method);
печатает:
Path::Router->dump is really Moose::Object::dump
Подобные звонки также раскрывающие такие вещи, как:
Net::SMTP->mail is really Net::SMTP::mail
Net::SMTP->status is really Net::Cmd::status
Net::SMTP->error is really IO::Handle::error
Он прекрасно работает на равнинных Ole подпрограммами тоже:
SQL::Translator::Parser::Storable->normalize_name
is really SQL::Translator::Utils::normalize_name
l l ovely comes_from
метод не довольно встроен, хотя он не требует ничего за пределами Стандартный Perl. Для того, чтобы сделать его доступным для вас и всех ваших классов и объектов и многое другое, просто добавьте этот кусок кода где-то - в любом месте, пожалуйста, на самом деле :)
sub UNIVERSAL::comes_from($$) {
require B;
my($invocant, $invoke) = @_;
my $coderef = $invocant->can($invoke) || return;
my $cv = B::svref_2object($coderef);
return unless $cv->isa("B::CV");
my $gv = $cv->GV;
return if $gv->isa("B::SPECIAL");
my $subname = $gv->NAME;
my $packname = $gv->STASH->NAME;
return $packname . "::" . $subname;
}
Объявив, что в UNIVERSAL
подразделам, теперь все, кто-нибудь получает играйте с ним, как и в случае с can
и isa
. Наслаждайтесь!
Серьезно, если у вас нет * тон * методов в разных классах, все называемые 'mystery',' ack '^ sub mystery'' действительно являются наилучшим способом найти, где этот метод определен. –
Вы не даете понять, как вы хотите использовать эту информацию. Я хотел бы, чтобы он был доступен в программной среде IDE, но поскольку вы запрашиваете * «какой-то модуль отладки» *, делает ли стандартный отладчик то, что вы хотите? Вы можете просто использовать 's' для шага * в * вызов метода и посмотреть, где он вас принимает. – Borodin
@jcast - нет, не совсем. 'mystery' может быть атрибутом Moose. Или используйте для этого репо, это может быть либо 'sub', либо' method', в зависимости от того, кто его написал. Или он может быть определен как метод обработчика: 'имеет foo => (is => 'ro', handles => [qw (bar mystery baz)]' –