📄 mac.pm
字号:
package File::Spec::Mac;use strict;use vars qw(@ISA $VERSION);require File::Spec::Unix;$VERSION = '3.2501';@ISA = qw(File::Spec::Unix);my $macfiles;if ($^O eq 'MacOS') { $macfiles = eval { require Mac::Files };}sub case_tolerant { 1 }=head1 NAMEFile::Spec::Mac - File::Spec for Mac OS (Classic)=head1 SYNOPSIS require File::Spec::Mac; # Done internally by File::Spec if needed=head1 DESCRIPTIONMethods for manipulating file specifications.=head1 METHODS=over 2=item canonpathOn Mac OS, there's nothing to be done. Returns what it's given.=cutsub canonpath { my ($self,$path) = @_; return $path;}=item catdir()Concatenate two or more directory names to form a path separated by colons(":") ending with a directory. Resulting paths are B<relative> by default,but can be forced to be absolute (but avoid this, see below). Automaticallyputs a trailing ":" on the end of the complete path, because that's what'sdone in MacPerl's environment and helps to distinguish a file path from adirectory path.B<IMPORTANT NOTE:> Beginning with version 1.3 of this module, the resultingpath is relative by default and I<not> absolute. This decision was made dueto portability reasons. Since C<File::Spec-E<gt>catdir()> returns relative pathson all other operating systems, it will now also follow this convention on MacOS. Note that this may break some existing scripts.The intended purpose of this routine is to concatenate I<directory names>.But because of the nature of Macintosh paths, some additional possibilitiesare allowed to make using this routine give reasonable results for somecommon situations. In other words, you are also allowed to concatenateI<paths> instead of directory names (strictly speaking, a string like ":a"is a path, but not a name, since it contains a punctuation character ":").So, beside calls like catdir("a") = ":a:" catdir("a","b") = ":a:b:" catdir() = "" (special case)calls like the following catdir(":a:") = ":a:" catdir(":a","b") = ":a:b:" catdir(":a:","b") = ":a:b:" catdir(":a:",":b:") = ":a:b:" catdir(":") = ":"are allowed.Here are the rules that are used in C<catdir()>; note that we try to be ascompatible as possible to Unix:=over 2=item 1.The resulting path is relative by default, i.e. the resulting path will have aleading colon.=item 2.A trailing colon is added automatically to the resulting path, to denote adirectory.=item 3.Generally, each argument has one leading ":" and one trailing ":"removed (if any). They are then joined together by a ":". Specialtreatment applies for arguments denoting updir paths like "::lib:",see (4), or arguments consisting solely of colons ("colon paths"),see (5).=item 4.When an updir path like ":::lib::" is passed as argument, the numberof directories to climb up is handled correctly, not removing leadingor trailing colons when necessary. E.g. catdir(":::a","::b","c") = ":::a::b:c:" catdir(":::a::","::b","c") = ":::a:::b:c:"=item 5.Adding a colon ":" or empty string "" to a path at I<any> positiondoesn't alter the path, i.e. these arguments are ignored. (When a ""is passed as the first argument, it has a special meaning, see(6)). This way, a colon ":" is handled like a "." (curdir) on Unix,while an empty string "" is generally ignored (seeC<Unix-E<gt>canonpath()> ). Likewise, a "::" is handled like a ".."(updir), and a ":::" is handled like a "../.." etc. E.g. catdir("a",":",":","b") = ":a:b:" catdir("a",":","::",":b") = ":a::b:"=item 6.If the first argument is an empty string "" or is a volume name, i.e. matchesthe pattern /^[^:]+:/, the resulting path is B<absolute>.=item 7.Passing an empty string "" as the first argument to C<catdir()> islike passingC<File::Spec-E<gt>rootdir()> as the first argument, i.e. catdir("","a","b") is the same as catdir(rootdir(),"a","b").This is true on Unix, where C<catdir("","a","b")> yields "/a/b" andC<rootdir()> is "/". Note that C<rootdir()> on Mac OS is the startupvolume, which is the closest in concept to Unix' "/". This should helpto run existing scripts originally written for Unix.=item 8.For absolute paths, some cleanup is done, to ensure that the volumename isn't immediately followed by updirs. This is invalid, becausethis would go beyond "root". Generally, these cases are handled liketheir Unix counterparts: Unix: Unix->catdir("","") = "/" Unix->catdir("",".") = "/" Unix->catdir("","..") = "/" # can't go beyond root Unix->catdir("",".","..","..","a") = "/a" Mac: Mac->catdir("","") = rootdir() # (e.g. "HD:") Mac->catdir("",":") = rootdir() Mac->catdir("","::") = rootdir() # can't go beyond root Mac->catdir("",":","::","::","a") = rootdir() . "a:" # (e.g. "HD:a:")However, this approach is limited to the first arguments following"root" (again, see C<Unix-E<gt>canonpath()> ). If there are morearguments that move up the directory tree, an invalid path goingbeyond root can be created.=backAs you've seen, you can force C<catdir()> to create an absolute pathby passing either an empty string or a path that begins with a volumename as the first argument. However, you are strongly encouraged notto do so, since this is done only for backward compatibility. Newerversions of File::Spec come with a method called C<catpath()> (seebelow), that is designed to offer a portable solution for the creationof absolute paths. It takes volume, directory and file portions andreturns an entire path. While C<catdir()> is still suitable for theconcatenation of I<directory names>, you are encouraged to useC<catpath()> to concatenate I<volume names> and I<directorypaths>. E.g. $dir = File::Spec->catdir("tmp","sources"); $abs_path = File::Spec->catpath("MacintoshHD:", $dir,"");yields "MacintoshHD:tmp:sources:" .=cutsub catdir { my $self = shift; return '' unless @_; my @args = @_; my $first_arg; my $relative; # take care of the first argument if ($args[0] eq '') { # absolute path, rootdir shift @args; $relative = 0; $first_arg = $self->rootdir; } elsif ($args[0] =~ /^[^:]+:/) { # absolute path, volume name $relative = 0; $first_arg = shift @args; # add a trailing ':' if need be (may be it's a path like HD:dir) $first_arg = "$first_arg:" unless ($first_arg =~ /:\Z(?!\n)/); } else { # relative path $relative = 1; if ( $args[0] =~ /^::+\Z(?!\n)/ ) { # updir colon path ('::', ':::' etc.), don't shift $first_arg = ':'; } elsif ($args[0] eq ':') { $first_arg = shift @args; } else { # add a trailing ':' if need be $first_arg = shift @args; $first_arg = "$first_arg:" unless ($first_arg =~ /:\Z(?!\n)/); } } # For all other arguments, # (a) ignore arguments that equal ':' or '', # (b) handle updir paths specially: # '::' -> concatenate '::' # '::' . '::' -> concatenate ':::' etc. # (c) add a trailing ':' if need be my $result = $first_arg; while (@args) { my $arg = shift @args; unless (($arg eq '') || ($arg eq ':')) { if ($arg =~ /^::+\Z(?!\n)/ ) { # updir colon path like ':::' my $updir_count = length($arg) - 1; while ((@args) && ($args[0] =~ /^::+\Z(?!\n)/) ) { # while updir colon path $arg = shift @args; $updir_count += (length($arg) - 1); } $arg = (':' x $updir_count); } else { $arg =~ s/^://s; # remove a leading ':' if any $arg = "$arg:" unless ($arg =~ /:\Z(?!\n)/); # ensure trailing ':' } $result .= $arg; }#unless } if ( ($relative) && ($result !~ /^:/) ) { # add a leading colon if need be $result = ":$result"; } unless ($relative) { # remove updirs immediately following the volume name $result =~ s/([^:]+:)(:*)(.*)\Z(?!\n)/$1$3/; } return $result;}=item catfileConcatenate one or more directory names and a filename to form acomplete path ending with a filename. Resulting paths are B<relative>by default, but can be forced to be absolute (but avoid this).B<IMPORTANT NOTE:> Beginning with version 1.3 of this module, theresulting path is relative by default and I<not> absolute. Thisdecision was made due to portability reasons. SinceC<File::Spec-E<gt>catfile()> returns relative paths on all otheroperating systems, it will now also follow this convention on Mac OS.Note that this may break some existing scripts.The last argument is always considered to be the file portion. SinceC<catfile()> uses C<catdir()> (see above) for the concatenation of thedirectory portions (if any), the following with regard to relative andabsolute paths is true: catfile("") = "" catfile("file") = "file"but catfile("","") = rootdir() # (e.g. "HD:") catfile("","file") = rootdir() . file # (e.g. "HD:file") catfile("HD:","file") = "HD:file"This means that C<catdir()> is called only when there are two or morearguments, as one might expect.Note that the leading ":" is removed from the filename, so that catfile("a","b","file") = ":a:b:file" and catfile("a","b",":file") = ":a:b:file"give the same answer.To concatenate I<volume names>, I<directory paths> and I<filenames>,you are encouraged to use C<catpath()> (see below).=cutsub catfile { my $self = shift; return '' unless @_; my $file = pop @_; return $file unless @_; my $dir = $self->catdir(@_); $file =~ s/^://s; return $dir.$file;}=item curdirReturns a string representing the current directory. On Mac OS, this is ":".=cutsub curdir { return ":";}=item devnullReturns a string representing the null device. On Mac OS, this is "Dev:Null".=cutsub devnull { return "Dev:Null";}=item rootdirReturns a string representing the root directory. Under MacPerl,returns the name of the startup volume, since that's the closest inconcept, although other volumes aren't rooted there. The name has atrailing ":", because that's the correct specification for a volumename on Mac OS.If Mac::Files could not be loaded, the empty string is returned.=cutsub rootdir {## There's no real root directory on Mac OS. The name of the startup# volume is returned, since that's the closest in concept.# return '' unless $macfiles; my $system = Mac::Files::FindFolder(&Mac::Files::kOnSystemDisk, &Mac::Files::kSystemFolderType); $system =~ s/:.*\Z(?!\n)/:/s; return $system;}=item tmpdirReturns the contents of $ENV{TMPDIR}, if that directory exits or thecurrent working directory otherwise. Under MacPerl, $ENV{TMPDIR} willcontain a path like "MacintoshHD:Temporary Items:", which is a hiddendirectory on your startup volume.=cutmy $tmpdir;sub tmpdir { return $tmpdir if defined $tmpdir; $tmpdir = $_[0]->_tmpdir( $ENV{TMPDIR} );}=item updirReturns a string representing the parent directory. On Mac OS, this is "::".=cutsub updir { return "::";}=item file_name_is_absoluteTakes as argument a path and returns true, if it is an absolute path.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -