views:

356

answers:

3

I would like to translate a Perl package name to the full path of the file.

say package_name_to_path('Foo::Bar::Baz');
/tmp/Foo/Bar/Baz.pm

I know there is a CPAN module to do this? I just can't find it again?

+3  A: 

Doh - I just remembered.

use Module::Util qw( :all );

$valid = is_valid_module_name $potential_module;

$relative_path = module_path $module_name;

$file_system_path = module_fs_path $module_name;
git-noob
There is also the module_info program which comes with Module::Info.
Schwern
+3  A: 

Well, perldoc can tell you the filename:

[fayland@alpha ~]$ perldoc -l Catalyst
/home/fayland/perl5/lib/perl5/Catalyst.pm

or look in %INC after you've loaded the module.

Thanks.

Fayland Lam
perldoc -l will not find modules which have no POD. Usually this is not a problem.
Schwern
+8  A: 

If you've loaded the module, just look in %INC but you have to do it by filename.

say $INC{"Foo/Bar/Baz.pm"};

If you haven't, you can use Module::Util or the module_info program which comes with Module::Info.

$ module_info Module::Build

Name:        Module::Build
Version:     0.30
Directory:   /usr/local/lib/site_perl
File:        /usr/local/lib/site_perl/Module/Build.pm
Core module: no

Or you can go through @INC manually.

my $module = "Foo::Bar";

# Convert from Foo::Bar to Foo/Bar.pm
my $file   = $module;
$file =~ s{::}{/};
$file .= ".pm";

my $path;
for my $dir (@INC) {
    $path = "$dir/$file";
    last if -r $path;
    $path = undef;
}

say defined $path ? "$module is found at $path" : "$module not found";

(A fully cross platform solution would use File::Spec instead of joining with slashes.)

If you just need to find a module quick, perldoc -l works well as Fayland mentioned, but it will fail to find a module that has no POD.

Schwern
Don't forget if you're pulling it out of %INC you have to mangle the module name a bit. Your first example would have to be: say $INC{"Foo/Bar/Baz.pm"}
Brian Phillips
You're right! PS Community wiki answer, you're free to edit.
Schwern