На самом деле, причуды задокументированы в документации для самих функций Perl.
http://search.cpan.org/~rjbs/perl-5.16.0/lib/File/Basename.pm#basename
Эта функция предназначена для совместимости с оболочкой Unix.
Базовое имя команды (1). НЕ всегда возвращает часть имени файла
пути, как вы могли ожидать. ... basename () возвращает последний уровень
пути к файлу, даже если последний уровень явно является каталогом. ... Также
обратите внимание, что для совместимости с командой оболочки, basename ()
не снимает суффикс, если он идентичен остальному
символы в имени файла.
Другими словами, basename("dir/")
- это "dir/"
, а не ""
; и basename("dir/.txt", ".txt")
является ".txt"
, а не ""
.
http://search.cpan.org/~rjbs/perl-5.16.0/lib/File/Basename.pm#dirname
Причуды dirname
гораздо более причудливы и зависят от текущего значения $File::Basename::Fileparse_fstype
. Я просто вставлю сюда код, так как он короткий.
sub dirname {
my $path = shift;
my($type) = $Fileparse_fstype;
if( $type eq 'VMS' and $path =~ m{/} ) {
# Parse as Unix
local($File::Basename::Fileparse_fstype) = '';
return dirname($path);
}
my($basename, $dirname) = fileparse($path);
if ($type eq 'VMS') {
$dirname ||= $ENV{DEFAULT};
} elsif ($type eq 'MacOS') {
if( !length($basename) && $dirname !~ /^[^:]+:\z/) {
_strip_trailing_sep($dirname);
($basename,$dirname) = fileparse $dirname;
}
$dirname .= ":" unless $dirname =~ /:\z/;
} elsif (grep { $type eq $_ } qw(MSDOS DOS MSWin32 OS2)) {
_strip_trailing_sep($dirname);
unless( length($basename) ) {
($basename,$dirname) = fileparse $dirname;
_strip_trailing_sep($dirname);
}
} elsif ($type eq 'AmigaOS') {
if ( $dirname =~ /:\z/) { return $dirname }
chop $dirname;
$dirname =~ s{[^:/]+\z}{} unless length($basename);
} else {
_strip_trailing_sep($dirname);
unless( length($basename) ) {
($basename,$dirname) = fileparse $dirname;
_strip_trailing_sep($dirname);
}
}
$dirname;
}
# Strip the trailing path separator.
sub _strip_trailing_sep {
my $type = $Fileparse_fstype;
if ($type eq 'MacOS') {
$_[0] =~ s/([^:]):\z/$1/s;
} elsif (grep { $type eq $_ } qw(MSDOS DOS MSWin32 OS2)) {
$_[0] =~ s/([^:])[\\\/]*\z/$1/;
} else {
$_[0] =~ s{(.)/*\z}{$1}s;
}
}