如何从Perl模块位置获取Perl包名

如何从Perl模块位置获取Perl包名,perl,Perl,下面的代码将找到Perl模块的路径并将其存储在@files数组中。 我尝试了从perl模块路径中删除@INC path的regexp,但没有成功。 请告诉我从给定的模块路径获取Perl模块名的更好方法 #Get locally installed Perl module path my @files = (); find({ wanted => sub { push @files, $File::Find::fullname if

下面的代码将找到Perl模块的路径并将其存储在@files数组中。 我尝试了从perl模块路径中删除@INC path的regexp,但没有成功。 请告诉我从给定的模块路径获取Perl模块名的更好方法

#Get locally installed Perl module path
my @files = ();
find({
    wanted => sub {
            push @files, $File::Find::fullname
              if defined $File::Find::fullname && -f $File::Find::fullname && /\.pm$/
        },
    follow => 1,
    follow_skip => 2,
}, @INC);

# Make the hash with Perl Module Path and Perl Module Name
my ($file_path, $name) = ("", "");
my %modules = ();
foreach $file_path (@files) { #loop through all the perl module (.pms) found
    for (@INC) {#replace the path with scope resolution operator
        if ($_ !~ /^\.$/) {
            if ($file_path =~ /$_/) {
                ($name = $file_path) =~ s/$_//g;
                $name =~ s/\//::/g;
                $name =~ s/\.pm$//g;
                $modules{$file_path} = $name;
            }
        }
    }
}

如果模块已经通过标准的
use
语句加载,那么最好的方法可能是执行以下操作:

my %CNI = reverse %INC;
my $module = $CNI{$filename};
$module =~ s{[.]pmc?$}{};
$module =~ s{/}{::}g;

在一般情况下,try-这会扫描模块的源代码,并在其中找到
package
语句。Module::Metadata从Perl 5.14开始就与Perl捆绑在一起。

对于像DBIx::Class::Carp这样的包,Module::Metadata不会打印包信息,因为模块中缺少包信息。不管怎样,我也可以为它们获取包名吗?最终,您只需接受模块和包之间没有一对一的对应关系,并且没有完美的解决方案。一个模块可以定义一个包、多个包或不定义包。相反,一个包定义可以拆分为多个模块,这些模块都需要加载才能将包视为“完整的”。