基地名怪癖 - 他们是什么

时间:2010-09-09 08:45:58

标签: perl

File :: Basename的文档说

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. 

这些怪癖是什么?

2 个答案:

答案 0 :(得分:1)

每个函数的man页面都记录了这个怪癖:


man dirname
  

说明

     

打印NAME,删除其尾随/组件;如果NAME包含   不,输出'。' (意思是   当前目录)。

     

示例

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

dirname stdio.h
        Output ".".

man basename
  

<强>描述

     

使用任何首要目录打印NAME   组件已删除。如果指定,   同时删除一个尾随的SUFFIX。

     

示例

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

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

答案 1 :(得分:1)

实际上,这些怪癖记录在Perl函数本身的文档中。 http://search.cpan.org/~rjbs/perl-5.16.0/lib/File/Basename.pm#basename

  

提供此功能是为了与Unix shell兼容   命令basename(1)。它并不总是返回文件名部分   你可能期望的路径... basename()返回最后一级   即使最后一级是明确的目录,也是文件路径的。 ......还有   请注意,为了与shell命令兼容,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;
    }
}