2012-06-03 3 views
7

Есть ли стандартный способ CPAN для определения всех суперклассов класса Perl (или, лучше всего, всего дерева суперкласса, до UNIVERSAL)?Какова наилучшая практика для определения всех суперклассов класса Perl?

Или лучше всего просто изучить @{"${$class}::ISA"} для каждого класса, родителей класса и т. Д. ...?

+1

Возможно, это трюк, ответ на который вы не хотите делать? Иногда вы должны просто позволить полиморфизму делать свое дело. Обычно даже, возможно. – tchrist

+0

@tchrist - не трюк. Мне никогда не приходилось это делать (как отмечено вашим комментарием и ответами, это не то, что обычно нужно делать); так что, когда возникает необходимость рассмотреть вопрос о том, «как» возникла при ответе на это [http://stackoverflow.com/questions/10869511/is-there-a-way-to-know-the-methods-of-an-instance -of-an-unknown-class-in-perl/10869712 # 10869712), я столкнулся с необходимостью выбрать реализацию AN. И я твердо верю в TIMTOWTDIBSWABTO. – DVK

ответ

8

Нет стандартного способа, потому что это не стандартная вещь, которую вы хотите сделать. Для чего угодно, кроме визуализации, это красный флаг OO, который хочет проверить ваше дерево наследования.

В дополнение к классу :: ISA, есть mro::get_linear_isa(). Оба были в ядре на некоторое время, поэтому их можно было считать «стандартными» для некоторого определения. Оба они показывают наследование как плоский список, а не дерево, которое полезно в основном для глубокой магии.

perl5i meta object обеспечивает как linear_isa(), как MRO (он просто вызывает MRO), и ISA(), который возвращает класс @ISA. Его можно использовать для построения дерева с использованием простой рекурсии без попадания в таблицы символов.

use perl5i::2; 

func print_isa_tree($class, $depth) { 
    $depth ||= 0; 

    my $indent = " " x $depth; 
    say $indent, $class; 

    for my $super_class ($class->mc->ISA) { 
     print_isa_tree($super_class, $depth+1); 
    } 

    return; 
} 


my $Class = shift; 
$Class->require; 

print_isa_tree($Class); 

__END__ 
DBIx::Class 
    DBIx::Class::Componentised 
     Class::C3::Componentised 
    DBIx::Class::AccessorGroup 
     Class::Accessor::Grouped 
+0

«На какое-то время» - можете ли вы количественно оценить это, пожалуйста? 5.12+? 5.8+? – DVK

+0

Ничего. Слишком ленив для Google. «Класс :: ISA был представлен в Perl Core в выпуске 5.8.0» (из [«Скрытые сокровища Perl Core» @ perl.com] (http://www.perl.com/pub/2003/05/29 /treasures.html)); – DVK

+0

@DVK См. Также [corelist] (http://search.cpan.org/perldoc?corelist) – Schwern

1

Я не верю, что есть что-то вроде «стандартного способа CPAN». Изучение @ISA является обычной практикой - а также правдоподобно, так как методы, как use base qw(...) и use parent -norequire, ... также работают на вершине @ISA ...

+0

«стандарт», как в «Использовать текст :: CSV {_XS}?» является стандартом для синтаксического анализа CSV. Да, есть gazillion модули для синтаксического анализа CSV, но этот или 1-2 других наиболее зрелые, используемые подавляющим большинством разработчиков и т. Д. ... – DVK

+0

ОК, сделанный пункт. Ну, в любом случае, я бы подумал о том, чтобы изучить «@ ISA» как «стандарт». – mjhennig

4

Я думаю Class::ISA это что-то, как вы ищете

use Class::ISA; 
use Mojolicious; 
print join "\n", Class::ISA::super_path("Mojolicious"); 

гравюр:

Mojo 
Mojo::Base 

Однако, это не какая-то «лучшая практика», поскольку вся задача - это не то, что программисты Perl делают каждый день.

0

Скорее всего в эти дни вы хотите использовать один из функций из mro, таких как mro::get_linear_isa.

use mro; 
my @superclasses = mro::get_linear_isa($class); 
+0

Тип возврата 'mro :: get_linear_isa' не является массивом, а arrayref !! – mikyra