In Perl, the /
is always reserved as a directory separator (except for the old Mac OS System [6-9] which insisted that it be :
). However, in other operating systems, other symbols could be used too. For example, on Windows machines, both of these refer to the same directory:
$file = 'C:\this\that\foo.txt';
$file = "C:/this/that/foo.txt";
So, you should always suspect that /
is a directory specifier unless you happen to be on an old Mac. And, you should also figure out what the current Path separator may be on that system and look for that one too.
I was hoping that File::Spec or File::Path might have some function or method that reveals the name of the preferred directory separator, but there's none documented.
Looking through the code of the various File::Spec
sub-modules, I see that the actual file separator is hard coded, and the functions are more complex than I originally thought. No special hidden function. Drat.
However, the good news is that File::Spec
is a standard module, so there's no reason to fear it. It was even included in Perl 5.8.8. You don't have to worry that it might not be installed.
I did a simple test:
#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);
use File::Spec;
while ( my $file = <DATA> ) {
chomp $file;
my ( $volume, $directory, $file ) = File::Spec->splitpath( $file );
if ( $directory ) {
say qq('$volume' '$directory' '$file' contains directory stuff);
}
else {
say qq('$volume' '$directory' '$file' is pure file);
}
}
__DATA__
Foo/Bar.txt
/Bar.txt
Bar.txt/
Foo_Bar.txt
The results were:
'' 'Foo/' 'Bar.txt' contains directory stuff
'' '/' 'Bar.txt' contains directory stuff
'' 'Bar.txt/' '' contains directory stuff
'' '' 'Foo_Bar.txt' is pure file
It appears that anytime a directory separator appears, the string is considered a file. I guess this makes sense.
This is one of those tasks that end up being way more complex than you realize (such as determining whether or not a string is a valid email address or a number). Your best bet is to use File::Spec->split
and make sure there's no volume or directory set.