开发者

Basename quirks - what are they

开发者 https://www.devze.com 2023-01-15 04:46 出处:网络
The documen开发者_开发问答tation for File::Basename says NOTE: \"dirname()\" and \"basename()\" emulate the behaviours, and quirks,

The documen开发者_开发问答tation for File::Basename says

NOTE: "dirname()" and "basename()" emulate the behaviours, and quirks,
of the shell and C functions of the same name. See each function's
documentation for details. 

What are these quirks?


Actually, the quirks are documented in the documentation for the Perl functions themselves. http://search.cpan.org/~rjbs/perl-5.16.0/lib/File/Basename.pm#basename

This function is provided for compatibility with the Unix shell command basename(1). It does NOT always return the file name portion of a path as you might expect. ... basename() returns the last level of a filepath even if the last level is clearly directory. ... Also note that in order to be compatible with the shell command, basename() does not strip off a suffix if it is identical to the remaining characters in the filename.

In other words, basename("dir/") is "dir/", not ""; and basename("dir/.txt", ".txt") is ".txt", not "".

http://search.cpan.org/~rjbs/perl-5.16.0/lib/File/Basename.pm#dirname The quirks of dirname are much quirkier, and depend on the current value of $File::Basename::Fileparse_fstype. I'll just paste the code here, since it's short.

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;
    }
}


The quirks are documented in the man pages for each function:


man dirname

DESCRIPTION

Print NAME with its trailing /component removed; if NAME contains no /'s, output '.' (meaning the current directory).

EXAMPLES

dirname /usr/bin/sort
        Output "/usr/bin".

dirname stdio.h
        Output ".".

man basename

DESCRIPTION

Print NAME with any leading directory components removed. If specified, also remove a trailing SUFFIX.

EXAMPLES

basename /usr/bin/sort
        Output "sort".

basename include/stdio.h .h
        Output "stdio".
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号