Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

How can a package knows which path it is in? For example, I have a "test.pm" in "/www/somedir": package test; sub currDIR { use Cwd; print getcwd(); } and then a "main.cgi" in "/www": require "./somedir/test.pm"; test::currDIR(); running main.cgi will print me "/www" (path to main.cgi), however, I a +ctually want "/www/somedir" (path to test.pm) instead, which command +should I use? I'm asking this because I need to open certain files i +n the package, and those files are stored in the same directory as th +e package for portability issues. Thank you.

Replies are listed 'Best First'.
Re: current path in a package?
by tilly (Archbishop) on Dec 28, 2010 at 06:41 UTC
    Check perldata for __FILE__ which gives you the full filename of the current file. File::Spec's splitpath should give you the directory that that file is in. (Or you can parse it out yourself pretty easily, if you don't care about portability.)
      Thanks a lot tilly!
Re: current path in a package?
by samarzone (Pilgrim) on Dec 28, 2010 at 08:06 UTC

    If you are using require with a physical path to the module file you already know the path. If you are concerned with absolute path rather than relative one you can use getcwd() prepended to the relative path mentioned in the require statement.

    If you will use the module rather than requireing it you will find absolute path of module file into %INC hash variable with key as the module name.

    use lib '/www/somedir/' use test; print $INC{test};
    --
    Regards
    - Samar

      Tilly suggested using __FILE__ because using cwd is not necessarily reliable. A script might have changed the current directory after it has been loaded. Additionally, a module can be loaded from any of the paths in @INC and may never have been reachable via the current directory in the first place.

      Note: __FILE__ only works for packages defined in the current file. If you want to find the location of an arbitrary package, look up the package in %INC. %INC contains a set of entries like this:

      Carp.pm => '/usr/share/perl/5.8/Carp.pm' vars.pm => '/usr/share/perl/5.8/vars.pm' List/Util.pm => '/usr/lib/perl/5.8/List/Util.pm'

      In %INC the module name gets ".pm" tacked onto the end and all of the '::' are replaced by '/'. I believe this transformation is consistent across platforms, so to look up the location of an arbitrary package:

      my $k = $module_name; $k =~ s/::/\//g; $k .= '.pm'; my $path = $INC{$k};
      .