This little function will return the full location (path) for a given module name (or undef if not found). For example, if you pass it 'CGI::Fast', it might return '/usr/lib/perl5/5.00503/CGI/Fast.pm'.

This can be useful for finding the location of a given module that you're using, or for converting the module names (in that nice and easy Module Name Format) to the fully qualified path-to-file so that you can open it for reading or what-have-you.

Note: As posted here, the snippet auto-adds the current directory to the search path (and will double search the current directory if @INC contains it already). This is for convience in finding user-installed modules. You can change this quite easily by removing the '.', part from the foreach loop.

Update:Note also that you can specify a path in the module name and it will search there first (eg: '/CGI' will look for CGI.pm in the root directory first). If not found, it strips off any leading path info and searches for just the file. (I fixed this behaviour slightly (read: I added it real quick), as leading path info messed up the first version I posted.)

Update 2:Fixed a problem with the checking specified paths interfereing with nested modules (eg: Text::Template).

sub mod2file { my $modname = shift or return undef; my $filename = ($modname !~ m|^(.*/)?[^/]*\.[^/]*$|) ? "$modname.pm" : $modname; $filename =~ s|^(.*/)||; # Strip leading path info ... my $startpath = $1; # ... but save it in $startpath. $filename =~ s|::|/|g; return "$startpath$filename" if($modname =~ m|/| and -e "$startpath$filename"); foreach my $basedir ('.', @INC) { return "$basedir/$filename" if(-e "$basedir/$filename"); } return undef; }

Replies are listed 'Best First'.
Re: Translating Module Names to File Names
by chipmunk (Parson) on Feb 21, 2001 at 04:01 UTC
    On the command line, I usually use perldoc -l for this purpose. For example: % emacs `perldoc -l CGI`

      Ah, good. I didn't know about the -l switch. But really, I wanted to avoid making a call to an external program to translate the filename (though I suppose that's a lot better than what I was doing (opening a pipe to perldoc -m Module to read the file in) and it would be more robust than what I have).

      Well, putting aside for the moment the fact that I'm reinventing a little wheel, I'd like to know what everyone thinks about my implementation. Is there anything I'm missing that would cause this to choke? Am I totally going about it wrong? Or does it look Ok?

      bbfu
      Seasons don't fear The Reaper.
      Nor do the wind, the sun, and the rain.
      We can be like they are.

Re: Translating Module Names to File Names
by japhy (Canon) on Feb 21, 2001 at 03:11 UTC

      Hrm, perhaps you're misunderstanding the purpose of this function. I'm not trying to duplicate the function of %INC. The function is there so you can look up the filenames for modules that you might not want to load.

      An example: I wrote a program that would let you view the source to Perl modules (yes, I know you can just do perldoc -m ModuleName, but this program will do syntax highlighting for you... I plan to post it here before too long, along with the syntax highlighting module I wrote) and it needed to translate the name of the module in Module Name Format to a fully qualified file name.

      bbfu
      Seasons don't fear The Reaper.
      Nor do the wind, the sun, and the rain.
      We can be like they are.

Re: Translating Module Names to File Names
by Maclir (Curate) on Feb 21, 2001 at 04:28 UTC
    Well, if I have a "use mymodule.pm;" in my code, how does perl work out when the physical file is to actually include the module code? The @INC array contains the list of places that perl looks in. So I thing your approach of going through this array is sound.

    Since @INC can be modified at run time, this will guarantee that you are looking at exactly what perl itself will look at at the time you call the function. This is probably the safest (read: most reliable) way to get the file name.

      Ah, yes. @INC can be modified at run time. And a `perldoc -l $module` wouldn't pick that up, now would it? So there ya go, chipmunk, Maclir agrees with me. ;-)

      Anyway, thanks for your perspective, Maclir (and chipmunk too!). I was suddenly afraid I was doing something stupid. =)

      bbfu
      Seasons don't fear The Reaper.
      Nor do the wind, the sun, and the rain.
      We can be like they are.

        Well, I would not go so far as saying "And a `perldoc -l $module` wouldn't pick that up, now would it?". I guess it all depends on how that process is spawned - I would have thought it ran in the same shell environment (but what do I know?)

        Maybe someone should test it and see?