Question

I am using the

my $file = <*.ext>;

function within Perl to test if a file exists (in this case, I need to know if there is a file with the .ext in the current working directory, otherwise I do not proceed) and throw an error if it doesn't. Such as:

my $file = <*.ext>;
if (-e $file) {
    # we are good
}
else {
    # file not found
}

As you can see I am bringing the input of the <*.ext> in to a scalar $variable, not an @array. This is probably not a good idea, but it's been working for me up until now and I have spent a while figuring out where my code was failing... and this seems to be it.

Seems that when switching directories (I am using "chdir", on a Windows machine) the current working directory switches properly but the input from the glob operator is very undefined and will look in previous directories, or is retaining past values.

I've been able to fix getting this to work by doing

my @file = <*.ext>;
if (-e $file[0]) {
}

and I'm wondering if anybody can explain this, because I've been unable to find where the return value of the glob operator is defined as an array or a scalar (if there is only one file, etc.)

Just trying to learn here to avoid future bugs. This was a requirement that it be in Perl on Windows and not something I regularly have to do, so my experience in this case is very thin. (More of a Python/C++ guy.)

Thanks.

Was it helpful?

Solution

perldoc -f glob explains this behavior

In list context, returns a (possibly empty) list of filename expansions on the value of EXPR such as the standard Unix shell /bin/csh would do. In scalar context, glob iterates through such filename expansions, returning undef when the list is exhausted.

So you are using iterator version which should be used with while to loop over it (all the way until it gets exhausted). As you clearly want to get only first value using list context you can,

my ($file) = <*.ext>;

OTHER TIPS

mpapec has already covered the perldoc glob documentation concerning the bahavior in a scalar context.

However, I'd just like to add that you can simplify your logic by putting the glob directly in the if

if (<*.ext>) {
    # we are good
}
else {
    # no files found
}

The testing of -e is superfluous as a file wouldn't have been returned by the glob if it didn't exist. Additionally, if you want to actually perform an operation on the found files, you can capture them inside the if

if (my @files = <*.ext>) {
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top