Re: abs_path($0) gags



pt wrote:
> I'm doing this:
>
> use Cwd qw/abs_path/ ;
> print "path to script = ",abs_path($0),"\n" ;
>
> And I get this:
> C:\>perl temp\Util.pl
> Uncaught exception from user code:
> Cannot chdir to temp\Util.pl: No such file or directory at
> temp\Util.pl line 147
> Cwd::_croak('Cannot chdir to temp\Util.pl: No such file or
> directory') called at C:/Program Files/ActiveState
> /Perl/lib/Cwd.pm line 432
> Cwd::fast_abs_path('temp\Util.pl') called at temp\Util.pl
line
> 147
>
>
> The help implies that it should return the path of the argument (the
> script name): abs_path and friends
> These functions are exported only on request. They each take a single
> argument and return the absolute pathname for it. If no argument is
> given they'll use the current working directory.


Good catch. I was able to successfully reproduce your problem, and
by using the debugger I noticed that the abs_path() function was
somehow calling the fast_abs_path() subroutine (I'm not exactly sure
why, but I think it might have to do with something in the XS code).

If you look at the fast_abs_path subroutine (do "perldoc -m Cwd" and
search for "sub fast_abs_path"), you'll notice that it has the line:

my $path = @_ ? shift : ($Curdir ||= File::Spec->curdir);

This line sets the $path to the first parameter, or to the current
directory (".") if there were no parameters passed in. Unfortunately,
the $path variable is treated a few lines later as a path to a
directory (not a file) with the conditional:

if (!CORE::chdir($path)) {
require Carp;
Carp::croak ("Cannot chdir to $path: $!");
}

This means that you are not allowed to pass in a full path to a
file, but rather to a directory (that is, if you do pass in a
paramether). Because of this restriction, I recommend you extract out
the directory path with dirname(), like this:


use Cwd qw/abs_path/;
use File::Basename;
print "path to script = ",
abs_path(-d $0 ? $0 : dirname($0)),
"\n" ;


The "-d" checks to see if $0 is a file or directory. If it is a
directory, it is passed as-is to abs_path(). If it's not a directory,
its directory path is passed to abs_path(). Of course, $0 should
always be a file, so "-d $0" will always fail, making the dirname()
function strip out the directory path of $0 (which could very well be
".").

I hope this helps.

-- Jean-Luc

.