📄 perlport.1
字号:
.PPDon't assume that a single \f(CW\*(C`unlink\*(C'\fR completely gets rid of the file:some filesystems (most notably the ones in \s-1VMS\s0) have versionedfilesystems, and \fIunlink()\fR removes only the most recent one (it doesn'tremove all the versions because by default the native tools on thoseplatforms remove just the most recent version, too). The portableidiom to remove all the versions of a file is.PP.Vb 1\& 1 while unlink "file";.Ve.PPThis will terminate if the file is undeleteable for some reason(protected, not there, and so on)..PPDon't count on a specific environment variable existing in \f(CW%ENV\fR.Don't count on \f(CW%ENV\fR entries being case-sensitive, or evencase-preserving. Don't try to clear \f(CW%ENV\fR by saying \f(CW\*(C`%ENV = ();\*(C'\fR, or,if you really have to, make it conditional on \f(CW\*(C`$^O ne \*(AqVMS\*(Aq\*(C'\fR since in\&\s-1VMS\s0 the \f(CW%ENV\fR table is much more than a per-process key-value stringtable..PPOn \s-1VMS\s0, some entries in the \f(CW%ENV\fR hash are dynamically created whentheir key is used on a read if they did not previously exist. Thevalues for \f(CW$ENV{HOME}\fR, \f(CW$ENV{TERM}\fR, \f(CW$ENV{HOME}\fR, and \f(CW$ENV{USER}\fR,are known to be dynamically generated. The specific names that aredynamically generated may vary with the version of the C library on \s-1VMS\s0,and more may exist than is documented..PPOn \s-1VMS\s0 by default, changes to the \f(CW%ENV\fR hash are persistent after the processexits. This can cause unintended issues..PPDon't count on signals or \f(CW%SIG\fR for anything..PPDon't count on filename globbing. Use \f(CW\*(C`opendir\*(C'\fR, \f(CW\*(C`readdir\*(C'\fR, and\&\f(CW\*(C`closedir\*(C'\fR instead..PPDon't count on per-program environment variables, or per-program currentdirectories..PPDon't count on specific values of \f(CW$!\fR, neither numeric norespecially the strings values\*(-- users may switch their locales causingerror messages to be translated into their languages. If you cantrust a POSIXish environment, you can portably use the symbols definedby the Errno module, like \s-1ENOENT\s0. And don't trust on the values of \f(CW$!\fRat all except immediately after a failed system call..Sh "Command names versus file pathnames".IX Subsection "Command names versus file pathnames"Don't assume that the name used to invoke a command or program with\&\f(CW\*(C`system\*(C'\fR or \f(CW\*(C`exec\*(C'\fR can also be used to test for the existence of thefile that holds the executable code for that command or program.First, many systems have \*(L"internal\*(R" commands that are built-in to theshell or \s-1OS\s0 and while these commands can be invoked, there is nocorresponding file. Second, some operating systems (e.g., Cygwin,\&\s-1DJGPP\s0, \s-1OS/2\s0, and \s-1VOS\s0) have required suffixes for executable files;these suffixes are generally permitted on the command name but are notrequired. Thus, a command like \*(L"perl\*(R" might exist in a file named\&\*(L"perl\*(R", \*(L"perl.exe\*(R", or \*(L"perl.pm\*(R", depending on the operating system.The variable \*(L"_exe\*(R" in the Config module holds the executable suffix,if any. Third, the \s-1VMS\s0 port carefully sets up $^X and\&\f(CW$Config\fR{perlpath} so that no further processing is required. This isjust as well, because the matching regular expression used below wouldthen have to deal with a possible trailing version number in the \s-1VMS\s0file name..PPTo convert $^X to a file pathname, taking account of the requirementsof the various operating system possibilities, say:.PP.Vb 4\& use Config;\& $thisperl = $^X;\& if ($^O ne \*(AqVMS\*(Aq)\& {$thisperl .= $Config{_exe} unless $thisperl =~ m/$Config{_exe}$/i;}.Ve.PPTo convert \f(CW$Config\fR{perlpath} to a file pathname, say:.PP.Vb 4\& use Config;\& $thisperl = $Config{perlpath};\& if ($^O ne \*(AqVMS\*(Aq)\& {$thisperl .= $Config{_exe} unless $thisperl =~ m/$Config{_exe}$/i;}.Ve.Sh "Networking".IX Subsection "Networking"Don't assume that you can reach the public Internet..PPDon't assume that there is only one way to get through firewallsto the public Internet..PPDon't assume that you can reach outside world through any other portthan 80, or some web proxy. ftp is blocked by many firewalls..PPDon't assume that you can send email by connecting to the local \s-1SMTP\s0 port..PPDon't assume that you can reach yourself or any node by the name\&'localhost'. The same goes for '127.0.0.1'. You will have to try both..PPDon't assume that the host has only one network card, or that itcan't bind to many virtual \s-1IP\s0 addresses..PPDon't assume a particular network device name..PPDon't assume a particular set of \fIioctl()\fRs will work..PPDon't assume that you can ping hosts and get replies..PPDon't assume that any particular port (service) will respond..PPDon't assume that Sys::Hostname (or any other \s-1API\s0 or command)returns either a fully qualified hostname or a non-qualified hostname:it all depends on how the system had been configured. Also rememberthings like \s-1DHCP\s0 and NAT\*(-- the hostname you get back might not be veryuseful..PPAll the above \*(L"don't\*(R":s may look daunting, and they are \*(-- but the keyis to degrade gracefully if one cannot reach the particular networkservice one wants. Croaking or hanging do not look very professional..Sh "Interprocess Communication (\s-1IPC\s0)".IX Subsection "Interprocess Communication (IPC)"In general, don't directly access the system in code meant to beportable. That means, no \f(CW\*(C`system\*(C'\fR, \f(CW\*(C`exec\*(C'\fR, \f(CW\*(C`fork\*(C'\fR, \f(CW\*(C`pipe\*(C'\fR,\&\f(CW\*(C`\`\`\*(C'\fR, \f(CW\*(C`qx//\*(C'\fR, \f(CW\*(C`open\*(C'\fR with a \f(CW\*(C`|\*(C'\fR, nor any of the other thingsthat makes being a perl hacker worth being..PPCommands that launch external processes are generally supported onmost platforms (though many of them do not support any type offorking). The problem with using them arises from what you invokethem on. External tools are often named differently on differentplatforms, may not be available in the same location, might acceptdifferent arguments, can behave differently, and often present theirresults in a platform-dependent way. Thus, you should seldom dependon them to produce consistent results. (Then again, if you're calling \&\fInetstat \-a\fR, you probably don't expect it to run on both Unix and \s-1CP/M\s0.).PPOne especially common bit of Perl code is opening a pipe to \fBsendmail\fR:.PP.Vb 2\& open(MAIL, \*(Aq|/usr/lib/sendmail \-t\*(Aq) \& or die "cannot fork sendmail: $!";.Ve.PPThis is fine for systems programming when sendmail is known to beavailable. But it is not fine for many non-Unix systems, and evensome Unix systems that may not have sendmail installed. If a portablesolution is needed, see the various distributions on \s-1CPAN\s0 that dealwith it. Mail::Mailer and Mail::Send in the MailTools distribution arecommonly used, and provide several mailing methods, including mail,sendmail, and direct \s-1SMTP\s0 (via Net::SMTP) if a mail transfer agent isnot available. Mail::Sendmail is a standalone module that providessimple, platform-independent mailing..PPThe Unix System V \s-1IPC\s0 (\f(CW\*(C`msg*(), sem*(), shm*()\*(C'\fR) is not availableeven on all Unix platforms..PPDo not use either the bare result of \f(CW\*(C`pack("N", 10, 20, 30, 40)\*(C'\fR orbare v\-strings (such as \f(CW\*(C`v10.20.30.40\*(C'\fR) to represent IPv4 addresses:both forms just pack the four bytes into network order. That thiswould be equal to the C language \f(CW\*(C`in_addr\*(C'\fR struct (which is what thesocket code internally uses) is not guaranteed. To be portable usethe routines of the Socket extension, such as \f(CW\*(C`inet_aton()\*(C'\fR,\&\f(CW\*(C`inet_ntoa()\*(C'\fR, and \f(CW\*(C`sockaddr_in()\*(C'\fR..PPThe rule of thumb for portable code is: Do it all in portable Perl, oruse a module (that may internally implement it with platform-specificcode, but expose a common interface)..Sh "External Subroutines (\s-1XS\s0)".IX Subsection "External Subroutines (XS)"\&\s-1XS\s0 code can usually be made to work with any platform, but dependentlibraries, header files, etc., might not be readily available orportable, or the \s-1XS\s0 code itself might be platform-specific, just as Perlcode might be. If the libraries and headers are portable, then it isnormally reasonable to make sure the \s-1XS\s0 code is portable, too..PPA different type of portability issue arises when writing \s-1XS\s0 code:availability of a C compiler on the end-user's system. C bringswith it its own portability issues, and writing \s-1XS\s0 code will exposeyou to some of those. Writing purely in Perl is an easier way toachieve portability..Sh "Standard Modules".IX Subsection "Standard Modules"In general, the standard modules work across platforms. Notableexceptions are the \s-1CPAN\s0 module (which currently makes connections to externalprograms that may not be available), platform-specific modules (likeExtUtils::MM_VMS), and \s-1DBM\s0 modules..PPThere is no one \s-1DBM\s0 module available on all platforms.SDBM_File and the others are generally available on all Unix and DOSishports, but not in MacPerl, where only NBDM_File and DB_File areavailable..PPThe good news is that at least some \s-1DBM\s0 module should be available, andAnyDBM_File will use whichever module it can find. Of course, thenthe code needs to be fairly strict, dropping to the greatest commonfactor (e.g., not exceeding 1K for each record), so that it willwork with any \s-1DBM\s0 module. See AnyDBM_File for more details..Sh "Time and Date".IX Subsection "Time and Date"The system's notion of time of day and calendar date is controlled inwidely different ways. Don't assume the timezone is stored in \f(CW$ENV{TZ}\fR,and even if it is, don't assume that you can control the timezone throughthat variable. Don't assume anything about the three-letter timezoneabbreviations (for example that \s-1MST\s0 would be the Mountain Standard Time,it's been known to stand for Moscow Standard Time). If you need touse timezones, express them in some unambiguous format like theexact number of minutes offset from \s-1UTC\s0, or the \s-1POSIX\s0 timezoneformat..PPDon't assume that the epoch starts at 00:00:00, January 1, 1970,because that is \s-1OS\-\s0 and implementation-specific. It is better tostore a date in an unambiguous representation. The \s-1ISO\s0 8601 standarddefines YYYY-MM-DD as the date format, or YYYY-MM-DDTHH-MM-SS(that's a literal \*(L"T\*(R" separating the date from the time).Please do use the \s-1ISO\s0 8601 instead of making us to guess whatdate 02/03/04 might be. \s-1ISO\s0 8601 even sorts nicely as-is.A text representation (like \*(L"1987\-12\-18\*(R") can be easily convertedinto an OS-specific value using a module like Date::Parse.An array of values, such as those returned by \f(CW\*(C`localtime\*(C'\fR, can beconverted to an OS-specific representation using Time::Local..PPWhen calculating specific times, such as for tests in time or date modules,it may be appropriate to calculate an offset for the epoch..PP.Vb 2\& require Time::Local;\& $offset = Time::Local::timegm(0, 0, 0, 1, 0, 70);.Ve.PPThe value for \f(CW$offset\fR in Unix will be \f(CW0\fR, but in Mac \s-1OS\s0 will besome large number. \f(CW$offset\fR can then be added to a Unix time valueto get what should be the proper value on any system..PPOn Windows (at least), you shouldn't pass a negative value to \f(CW\*(C`gmtime\*(C'\fR or\&\f(CW\*(C`localtime\*(C'\fR..Sh "Character sets and character encoding".IX Subsection "Character sets and character encoding"Assume very little about character sets..PPAssume nothing about numerical values (\f(CW\*(C`ord\*(C'\fR, \f(CW\*(C`chr\*(C'\fR) of characters.Do not use explicit code point ranges (like \exHH\-\exHH); use forexample symbolic character classes like \f(CW\*(C`[:print:]\*(C'\fR..PPDo not assume that the alphabetic characters are encoded contiguously(in the numeric sense). There may be gaps..PPDo not assume anything about the ordering of the characters.The lowercase letters may come before or after the uppercase letters;the lowercase and uppercase may be interlaced so that both \*(L"a\*(R" and \*(L"A\*(R"come before \*(L"b\*(R"; the accented and other international characters maybe interlaced so that a\*: comes before \*(L"b\*(R"..Sh "Internationalisation".IX Subsection "Internationalisation"If you may assume \s-1POSIX\s0 (a rather large assumption), you may readmore about the \s-1POSIX\s0 locale system from perllocale. The localesystem at least attempts to make things a little bit more portable,or at least more convenient and native-friendly for non-Englishusers. The system affects character sets and encoding, and dateand time formatting\*(--amongst other things..PPIf you really want to be international, you should consider Unicode.See perluniintro and perlunicode for more information..PPIf you want to use non-ASCII bytes (outside the bytes 0x00..0x7f) inthe \*(L"source code\*(R" of your code, to be portable you have to be explicitabout what bytes they are. Someone might for example be using yourcode under a \s-1UTF\-8\s0 locale, in which case random native bytes might beillegal (\*(L"Malformed \s-1UTF\-8\s0 ...\*(R") This means that for example embedding\&\s-1ISO\s0 8859\-1 bytes beyond 0x7f into your strings might cause troublelater. If the bytes are native 8\-bit bytes, you can use the \f(CW\*(C`bytes\*(C'\fRpragma. If the bytes are in a string (regular expression being acurious string), you can often also use the \f(CW\*(C`\exHH\*(C'\fR notation insteadof embedding the bytes as-is. (If you want to write your code in \s-1UTF\-8\s0,you can use the \f(CW\*(C`utf8\*(C'\fR.) The \f(CW\*(C`bytes\*(C'\fR and \f(CW\*(C`utf8\*(C'\fR pragmata areavailable since Perl 5.6.0..Sh "System Resources".IX Subsection "System Resources"If your code is destined for systems with severely constrained (ormissing!) virtual memory systems then you want to be \fIespecially\fR mindfulof avoiding wasteful constructs such as:.PP.Vb 3\& # NOTE: this is no longer "bad" in perl5.005\& for (0..10000000) {} # bad
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -