a,s5 has asked for the wisdom of the Perl Monks concerning the following question:

Greetings, Experienced Perl Monks,

I have a number of perl scripts that I use for data maintenance. I would like to build a web front end for them (in PHP, since the site I'm assisting with uses it exclusively). The perl scripts are stored in /basedir/perl and the admin pages are stored in /basedir/admin.

My question is this: does Perl have anything like the dirname() function in PHP, that, when used thusly, dirname(__FILE__);, will return the absolute path to the script, no matter where it is included from?

I have subdirectories of perl scripts that reference external files, and when I access them from PHP pages, the different working directory breaks it. I can't hardcode the paths, since it's a small component of a large project set up in a test directory. I also do not want to program in paths relative to the including pages, as I want the files to be still useful from the commandline.

I have tried using Cwd and Config::Find::Where. The latter works somewhat, but only on the outermost level: if I try to access a perl script that includes another one in another folder, Config::Find::Where cannot grok the path for that internal file.

Is there an obvious solution to this that I am missing?

Thanks a bundle,
Andy

Replies are listed 'Best First'.
Re: Relative paths in included files
by BUU (Prior) on Jun 04, 2004 at 23:17 UTC
    I'm a tad confused. Do you want the exact path location of the perl script itself? You use FindBin to find that, to quote from the synopsis:
    use FindBin; use lib "$FindBin::Bin/../lib"; or use FindBin qw($Bin); use lib "$Bin/../lib";
    If you want to know the exact path of modules you're including, the %INC hash should have that.
      Yes! That's exactly what I was looking for. Thank you very much.

      Andy

        Krang! No, sorry to reply to my own post here. It doesn't quite work.

        The FindBin::Real module does an admirable job of finding the directory for the calling script. But if there are any files included that use it, it fails in them. I want to find something that works an arbitrary number of levels deep. Here's the situation:

        /test.pl
        (in this context, Bin() should return '/')
        ('require's Bin()/config.pl and Bin()/scrape_courses/scrape_courses.pl)

        /scrape_courses/scrape_courses.pl
        (in this context, I want Bin() to return '/scrape_courses')
        ('require's Bin()/../config.pl and Bin()/scrape_courses.template)

        When I run test.pl, it gives me this error Cannot find current script './test.pl' at /scrape_courses/scrape_courses.pl line 30

        So it's still not doing just what I need: every file, 'require'd some arbitrary number of levels deep, needs to know the full path to itself without being hard coded.

        Thanks,
        Andy

Re: Relative paths in included files
by kragen (Sexton) on Jun 05, 2004 at 00:04 UTC
    %INC
Re: Relative paths in included files
by PodMaster (Abbot) on Jun 05, 2004 at 06:41 UTC
    C:\Temp>more t use File::Spec; die File::Spec->dirname( File::Spec->rel2abs(__FILE__) ); sub File::Spec::dirname { my $self = shift; return $self->catpath( ( $self->splitpath(shift) )[ 0, 1 ] ); } __END__ C:\Temp>perl t C:\Temp\ at t line 3. C:\Temp>move t f\a\d\e\a\w\a\ C:\Temp>perl f\a\d\e\a\w\a\t C:\Temp\f\a\d\e\a\w\a\ at f\a\d\e\a\w\a\t line 3. C:\Temp>

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

      That works like a charm. I've tested the heck out of it, and I pronounce it my long sought solution. Thank you so much!
      --Andy