0

パッケージ内のすべてのサブを一覧表示するには、いくつかの方法があります。

sub list_methods {
    my $package = shift;
    no strict 'refs';
    return grep { defined &{"$package\::$_"} } keys %{"$package\::"}
}

ただし、パッケージが「File::Basename」などの他のパッケージを「使用」する場合、「fileparse」などのサブも同様にリストされます。パッケージを「使用」する代わりに「要求」しようとしましたが、問題は解決できます。一方、パッケージを「必要とする」場合は、サブのフル パスを指定する必要があります。

何か考えはありますか?

4

2 に答える 2

3
use B qw( svref_2object );

sub list_nonimported_subs {
    my ($pkg_name) = @_;
    my $pkg = do { no strict 'refs'; *{ $pkg_name . '::' } };

    my @nonimported_subs;
    for my $name (keys %$pkg) {
       my $glob = $pkg->{$name};
       my $code = *$glob{CODE}
          or next;

       my $cv = svref_2object($code);
       my $orig_pkg_name = $cv->GV->STASH->NAME;
       next if $orig_pkg_name ne $pkg_name;

       push @nonimported_subs, $name;
    }

    return @nonimported_subs;
}

グロブ内の CV がインポートされているかどうかを示すフラグがありますが、B を使用してそれを取得する方法が見つからないため、__PACKAGE__検査中のパッケージに対してサブの をチェックします。

メソッドかそうでないか判別できないので、サブの名前を一般化しました。

于 2012-09-20T01:27:45.027 に答える
2

PPIはソースを解析するため、モジュールをロードする必要はありません。

use PPI;

my $source = $INC{'Some/Module.pm'};  # or whatever
my $Document = PPI::Document->new($source) or die "oops";
for my $sub ( @{ $Document->find('PPI::Statement::Sub') || [] } ) {
    unless ( $sub->forward ) {
        print $sub->name, "\n";
    }
}
于 2012-09-20T01:59:15.960 に答える