📄 mac.pm
字号:
If the path has a leading ":", it's a relative path. Otherwise, it's anabsolute path, unless the path doesn't contain any colons, i.e. it's a namelike "a". In this particular case, the path is considered to be relative(i.e. it is considered to be a filename). Use ":" in the appropriate placein the path if you want to distinguish unambiguously. As a special case,the filename '' is always considered to be absolute. Note that with version1.2 of File::Spec::Mac, this does no longer consult the local filesystem.E.g. File::Spec->file_name_is_absolute("a"); # false (relative) File::Spec->file_name_is_absolute(":a:b:"); # false (relative) File::Spec->file_name_is_absolute("MacintoshHD:"); # true (absolute) File::Spec->file_name_is_absolute(""); # true (absolute)=cutsub file_name_is_absolute { my ($self,$file) = @_; if ($file =~ /:/) { return (! ($file =~ m/^:/s) ); } elsif ( $file eq '' ) { return 1 ; } else { return 0; # i.e. a file like "a" }}=item pathReturns the null list for the MacPerl application, since the concept isusually meaningless under Mac OS. But if you're using the MacPerl tool underMPW, it gives back $ENV{Commands} suitably split, as is done in:lib:ExtUtils:MM_Mac.pm.=cutsub path {## The concept is meaningless under the MacPerl application.# Under MPW, it has a meaning.# return unless exists $ENV{Commands}; return split(/,/, $ENV{Commands});}=item splitpath ($volume,$directories,$file) = File::Spec->splitpath( $path ); ($volume,$directories,$file) = File::Spec->splitpath( $path, $no_file );Splits a path into volume, directory, and filename portions.On Mac OS, assumes that the last part of the path is a filename unless$no_file is true or a trailing separator ":" is present.The volume portion is always returned with a trailing ":". The directory portionis always returned with a leading (to denote a relative path) and a trailing ":"(to denote a directory). The file portion is always returned I<without> a leading ":".Empty portions are returned as empty string ''.The results can be passed to C<catpath()> to get back a path equivalent to(usually identical to) the original path.=cutsub splitpath { my ($self,$path, $nofile) = @_; my ($volume,$directory,$file); if ( $nofile ) { ( $volume, $directory ) = $path =~ m|^((?:[^:]+:)?)(.*)|s; } else { $path =~ m|^( (?: [^:]+: )? ) ( (?: .*: )? ) ( .* ) |xs; $volume = $1; $directory = $2; $file = $3; } $volume = '' unless defined($volume); $directory = ":$directory" if ( $volume && $directory ); # take care of "HD::dir" if ($directory) { # Make sure non-empty directories begin and end in ':' $directory .= ':' unless (substr($directory,-1) eq ':'); $directory = ":$directory" unless (substr($directory,0,1) eq ':'); } else { $directory = ''; } $file = '' unless defined($file); return ($volume,$directory,$file);}=item splitdirThe opposite of C<catdir()>. @dirs = File::Spec->splitdir( $directories );$directories should be only the directory portion of the path on systemsthat have the concept of a volume or that have path syntax that differentiatesfiles from directories. Consider using C<splitpath()> otherwise.Unlike just splitting the directories on the separator, empty directory names(C<"">) can be returned. Since C<catdir()> on Mac OS always appends a trailingcolon to distinguish a directory path from a file path, a single trailing colonwill be ignored, i.e. there's no empty directory name after it.Hence, on Mac OS, both File::Spec->splitdir( ":a:b::c:" ); and File::Spec->splitdir( ":a:b::c" );yield: ( "a", "b", "::", "c")while File::Spec->splitdir( ":a:b::c::" );yields: ( "a", "b", "::", "c", "::")=cutsub splitdir { my ($self, $path) = @_; my @result = (); my ($head, $sep, $tail, $volume, $directories); return ('') if ( (!defined($path)) || ($path eq '') ); return (':') if ($path eq ':'); ( $volume, $sep, $directories ) = $path =~ m|^((?:[^:]+:)?)(:*)(.*)|s; # deprecated, but handle it correctly if ($volume) { push (@result, $volume); $sep .= ':'; } while ($sep || $directories) { if (length($sep) > 1) { my $updir_count = length($sep) - 1; for (my $i=0; $i<$updir_count; $i++) { # push '::' updir_count times; # simulate Unix '..' updirs push (@result, '::'); } } $sep = ''; if ($directories) { ( $head, $sep, $tail ) = $directories =~ m|^((?:[^:]+)?)(:*)(.*)|s; push (@result, $head); $directories = $tail; } } return @result;}=item catpath $path = File::Spec->catpath($volume,$directory,$file);Takes volume, directory and file portions and returns an entire path. On Mac OS,$volume, $directory and $file are concatenated. A ':' is inserted if need be. Youmay pass an empty string for each portion. If all portions are empty, the emptystring is returned. If $volume is empty, the result will be a relative path,beginning with a ':'. If $volume and $directory are empty, a leading ":" (if any)is removed form $file and the remainder is returned. If $file is empty, theresulting path will have a trailing ':'.=cutsub catpath { my ($self,$volume,$directory,$file) = @_; if ( (! $volume) && (! $directory) ) { $file =~ s/^:// if $file; return $file ; } # We look for a volume in $volume, then in $directory, but not both my ($dir_volume, $dir_dirs) = $self->splitpath($directory, 1); $volume = $dir_volume unless length $volume; my $path = $volume; # may be '' $path .= ':' unless (substr($path, -1) eq ':'); # ensure trailing ':' if ($directory) { $directory = $dir_dirs if $volume; $directory =~ s/^://; # remove leading ':' if any $path .= $directory; $path .= ':' unless (substr($path, -1) eq ':'); # ensure trailing ':' } if ($file) { $file =~ s/^://; # remove leading ':' if any $path .= $file; } return $path;}=item abs2relTakes a destination path and an optional base path and returns a relative pathfrom the base path to the destination path: $rel_path = File::Spec->abs2rel( $path ) ; $rel_path = File::Spec->abs2rel( $path, $base ) ;Note that both paths are assumed to have a notation that distinguishes adirectory path (with trailing ':') from a file path (without trailing ':').If $base is not present or '', then the current working directory is used.If $base is relative, then it is converted to absolute form using C<rel2abs()>.This means that it is taken to be relative to the current working directory.If $path and $base appear to be on two different volumes, we will notattempt to resolve the two paths, and we will instead simply return$path. Note that previous versions of this module ignored the volumeof $base, which resulted in garbage results part of the time.If $base doesn't have a trailing colon, the last element of $base isassumed to be a filename. This filename is ignored. Otherwise all pathcomponents are assumed to be directories.If $path is relative, it is converted to absolute form using C<rel2abs()>.This means that it is taken to be relative to the current working directory.Based on code written by Shigio Yamaguchi.=cut# maybe this should be done in canonpath() ?sub _resolve_updirs { my $path = shift @_; my $proceed; # resolve any updirs, e.g. "HD:tmp::file" -> "HD:file" do { $proceed = ($path =~ s/^(.*):[^:]+::(.*?)\z/$1:$2/); } while ($proceed); return $path;}sub abs2rel { my($self,$path,$base) = @_; # Clean up $path if ( ! $self->file_name_is_absolute( $path ) ) { $path = $self->rel2abs( $path ) ; } # Figure out the effective $base and clean it up. if ( !defined( $base ) || $base eq '' ) { $base = $self->_cwd(); } elsif ( ! $self->file_name_is_absolute( $base ) ) { $base = $self->rel2abs( $base ) ; $base = _resolve_updirs( $base ); # resolve updirs in $base } else { $base = _resolve_updirs( $base ); } # Split up paths - ignore $base's file my ( $path_vol, $path_dirs, $path_file ) = $self->splitpath( $path ); my ( $base_vol, $base_dirs ) = $self->splitpath( $base ); return $path unless lc( $path_vol ) eq lc( $base_vol ); # Now, remove all leading components that are the same my @pathchunks = $self->splitdir( $path_dirs ); my @basechunks = $self->splitdir( $base_dirs ); while ( @pathchunks && @basechunks && lc( $pathchunks[0] ) eq lc( $basechunks[0] ) ) { shift @pathchunks ; shift @basechunks ; } # @pathchunks now has the directories to descend in to. # ensure relative path, even if @pathchunks is empty $path_dirs = $self->catdir( ':', @pathchunks ); # @basechunks now contains the number of directories to climb out of. $base_dirs = (':' x @basechunks) . ':' ; return $self->catpath( '', $self->catdir( $base_dirs, $path_dirs ), $path_file ) ;}=item rel2absConverts a relative path to an absolute path: $abs_path = File::Spec->rel2abs( $path ) ; $abs_path = File::Spec->rel2abs( $path, $base ) ;Note that both paths are assumed to have a notation that distinguishes adirectory path (with trailing ':') from a file path (without trailing ':').If $base is not present or '', then $base is set to the current workingdirectory. If $base is relative, then it is converted to absolute formusing C<rel2abs()>. This means that it is taken to be relative to thecurrent working directory.If $base doesn't have a trailing colon, the last element of $base isassumed to be a filename. This filename is ignored. Otherwise all pathcomponents are assumed to be directories.If $path is already absolute, it is returned and $base is ignored.Based on code written by Shigio Yamaguchi.=cutsub rel2abs { my ($self,$path,$base) = @_; if ( ! $self->file_name_is_absolute($path) ) { # Figure out the effective $base and clean it up. if ( !defined( $base ) || $base eq '' ) { $base = $self->_cwd(); } elsif ( ! $self->file_name_is_absolute($base) ) { $base = $self->rel2abs($base) ; } # Split up paths # igonore $path's volume my ( $path_dirs, $path_file ) = ($self->splitpath($path))[1,2] ; # ignore $base's file part my ( $base_vol, $base_dirs ) = $self->splitpath($base) ; # Glom them together $path_dirs = ':' if ($path_dirs eq ''); $base_dirs =~ s/:$//; # remove trailing ':', if any $base_dirs = $base_dirs . $path_dirs; $path = $self->catpath( $base_vol, $base_dirs, $path_file ); } return $path;}=back=head1 AUTHORSSee the authors list in I<File::Spec>. Mac OS support by Paul Schinder<schinder@pobox.com> and Thomas Wegner <wegner_thomas@yahoo.com>.=head1 COPYRIGHTCopyright (c) 2004 by the Perl 5 Porters. All rights reserved.This program is free software; you can redistribute it and/or modifyit under the same terms as Perl itself.=head1 SEE ALSOSee L<File::Spec> and L<File::Spec::Unix>. This package overrides theimplementation of these methods, not the semantics.=cut1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -