Yakov Dan
Yakov Dan

Reputation: 3347

Cwd::abs_path() returns undef

I have an issue with using abs_path(). I give this function a valid path, but I get undef as a return value. The path is read from the command line using the following code.

use warnings;
use strict;
use Data::Dumper;
use Cwd qw();

print scalar @ARGV;
print "\n";

print "$ARGV[0]\n";
print "$ARGV[1]\n";
print "$ARGV[2]\n";
my $val = $ARGV[2];
print "$val\n";
my $result = "";
$result = Cwd::abs_path($val);
print "$result\n";

The perl script is executed as follows:

perl pl_test.pl -results_dir = /home/user123/

I get the following result:

3
-results_dir
=
/home/user123/
/home/user123/
Use of uninitialized value in concatenation (.) or string at pl_test.pl line 16.

I have verified using the debugger that the issue is that $result gets undef as return value from Cwd::abs_path($val);. I don't understand why this happens

One of the comments prompted me to do some further testing. What I found is that there is a dependency on a trailing slash, in the following manner:

  1. if the directory does not exist: works without a trailing slash, returns undef with a trailing slash.

  2. if the directory is a sub directory of a directory that does not exist, always returns undef

  3. if the directory exists, will work in both cases, with or without a trailing slash

Upvotes: 6

Views: 3836

Answers (2)

zhouronghua
zhouronghua

Reputation: 1

realpath of perl don't answer well for patch end with "/", like "/home/"

which realpath of bash answer well,

so if u want to call realpath in perl, pay attention to trim last "/" first.

Upvotes: -1

zdim
zdim

Reputation: 66883

The Cwd does use the filesystem so you shouldn't ask it to work with non-existent paths.

I've confirmed the observation that it does in fact give me back a path with a non-existent directory if it is in the directory which does exist (and has no trailing slash!), otherwise not. However, this doesn't mean much as the module's purpose is to work with existing paths.

To work with file names in general, for which files need not exist, use the core File::Spec

perl -MCwd=abs_path -MFile::Spec=rel2abs -wE'
    say abs_path(".");
    say abs_path("./no/such") // "undef";
    say File::Spec->rel2abs("./no/such")
'

This prints

/home/my-user-name
undef
/home/my-user-name/no/such

The trailing slashes don't affect (meaningful) operations of either modules.

Another useful tool is Path::Tiny, with many methods for a variety of work with existing and non-existing paths.

Upvotes: 4

Related Questions