获取从Perl中的给定基类派生的类的列表

b5lpy0ml  于 2022-12-13  发布在  Perl
关注(0)|答案(2)|浏览(157)

给定一个基类和从它派生的类的列表:

package base
{
    # ...
}

package foo
{
    our @ISA = 'base';
    # ...
}

package bar
{
    our @ISA = 'base';
    # ...
}

是否有运行时方法来获取以base作为父类的类列表?

我知道我可以很容易地通过手动将他们的名字添加到列表中来解决这个问题,但是我想知道base本身是否可以告诉我谁继承了它。

w7t8yxp5

w7t8yxp51#

从Perl 5.10开始,Perl提供了一个名为mro的模块,其中包括一大堆用于检查类层次结构的函数。
您可以使用以下方法查找My::Class的子类:

use mro;

my $base_class = 'My::Class';
print "$_\n" for @{ mro::get_isarev( $base_class ) };

mro文档包含了各种警告,比如在'UNIVERSAL'包上调用它不能正常工作。还有其他一些情况,它处理得很糟糕,但是如果你“做正常的事情”,它应该能工作。

9lowa7mx

9lowa7mx2#

如果您不知道所有“潜在”类的名称,可以递归地遍历整个“命名空间”。

sub inspect {
    my ($package, $search_for) = @_;
    my @result;
    my $keys = 'sort keys (%' . $package . '::)';
    $package=~ s/main:://;
    my @keys = eval $keys;
    foreach my $lookup (@keys) {
        $lookup =~ s/main:://;
        if ($lookup =~ /(.*)::$/) {
            push @result, inspect($package.'::'.$1, $search_for);
        }
    }
    push @result, $package
         if $package->isa($search_for);
    return @result;
}

因此在您示例中:

print "Number of derived classes: " . (inspect('main', 'base') -1) .  "\n";

我们必须提取一个类,因为该类是它自己的示例。
AFAIK库不存储任何地方的“类树”。

相关问题