perlport.pod
来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· POD 代码 · 共 1,586 行 · 第 1/5 页
POD
1,586 行
and file suffix).Even when on a single platform (if you can call Unix a single platform),remember not to count on the existence or the contents of particularsystem-specific files or directories, like F</etc/passwd>,F</etc/sendmail.conf>, F</etc/resolv.conf>, or even F</tmp/>. Forexample, F</etc/passwd> may exist but not contain the encryptedpasswords, because the system is using some form of enhanced security.Or it may not contain all the accounts, because the system is using NIS. If code does need to rely on such a file, include a description of thefile and its format in the code's documentation, then make it easy forthe user to override the default location of the file.Don't assume a text file will end with a newline. They should,but people forget.Do not have two files or directories of the same name with differentcase, like F<test.pl> and F<Test.pl>, as many platforms havecase-insensitive (or at least case-forgiving) filenames. Also, trynot to have non-word characters (except for C<.>) in the names, andkeep them to the 8.3 convention, for maximum portability, onerous aburden though this may appear.Likewise, when using the AutoSplit module, try to keep your functions to8.3 naming and case-insensitive conventions; or, at the least,make it so the resulting files have a unique (case-insensitively)first 8 characters.Whitespace in filenames is tolerated on most systems, but not all,and even on systems where it might be tolerated, some utilitiesmight become confused by such whitespace.Many systems (DOS, VMS ODS-2) cannot have more than one C<.> in theirfilenames.Don't assume C<< > >> won't be the first character of a filename.Always use C<< < >> explicitly to open a file for reading, or evenbetter, use the three-arg version of open, unless you want the user tobe able to specify a pipe open. open(FILE, '<', $existing_file) or die $!;If filenames might use strange characters, it is safest to open itwith C<sysopen> instead of C<open>. C<open> is magic and cantranslate characters like C<< > >>, C<< < >>, and C<|>, which maybe the wrong thing to do. (Sometimes, though, it's the right thing.)Three-arg open can also help protect against this translation in caseswhere it is undesirable.Don't use C<:> as a part of a filename since many systems use that fortheir own semantics (Mac OS Classic for separating pathname components,many networking schemes and utilities for separating the nodename andthe pathname, and so on). For the same reasons, avoid C<@>, C<;> andC<|>.Don't assume that in pathnames you can collapse two leading slashesC<//> into one: some networking and clustering filesystems have specialsemantics for that. Let the operating system to sort it out.The I<portable filename characters> as defined by ANSI C are a b c d e f g h i j k l m n o p q r t u v w x y z A B C D E F G H I J K L M N O P Q R T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 . _ -and the "-" shouldn't be the first character. If you want to behypercorrect, stay case-insensitive and within the 8.3 namingconvention (all the files and directories have to be unique within onedirectory if their names are lowercased and truncated to eightcharacters before the C<.>, if any, and to three characters after theC<.>, if any). (And do not use C<.>s in directory names.)=head2 System InteractionNot all platforms provide a command line. These are usually platformsthat rely primarily on a Graphical User Interface (GUI) for userinteraction. A program requiring a command line interface mightnot work everywhere. This is probably for the user of the programto deal with, so don't stay up late worrying about it.Some platforms can't delete or rename files held open by the system,this limitation may also apply to changing filesystem metainformationlike file permissions or owners. Remember to C<close> files when youare done with them. Don't C<unlink> or C<rename> an open file. Don'tC<tie> or C<open> a file already tied or opened; C<untie> or C<close>it first.Don't open the same file more than once at a time for writing, as someoperating systems put mandatory locks on such files.Don't assume that write/modify permission on a directory gives theright to add or delete files/directories in that directory. That isfilesystem specific: in some filesystems you need write/modifypermission also (or even just) in the file/directory itself. In somefilesystems (AFS, DFS) the permission to add/delete directory entriesis a completely separate permission.Don't assume that a single C<unlink> completely gets rid of the file:some filesystems (most notably the ones in VMS) have versionedfilesystems, and unlink() 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 1 while unlink "file";This will terminate if the file is undeleteable for some reason(protected, not there, and so on).Don't count on a specific environment variable existing in C<%ENV>.Don't count on C<%ENV> entries being case-sensitive, or evencase-preserving. Don't try to clear %ENV by saying C<%ENV = ();>, or,if you really have to, make it conditional on C<$^O ne 'VMS'> since inVMS the C<%ENV> table is much more than a per-process key-value stringtable.On VMS, some entries in the %ENV hash are dynamically created whentheir key is used on a read if they did not previously exist. Thevalues for C<$ENV{HOME}>, C<$ENV{TERM}>, C<$ENV{HOME}>, and C<$ENV{USER}>,are known to be dynamically generated. The specific names that aredynamically generated may vary with the version of the C library on VMS,and more may exist than is documented.On VMS by default, changes to the %ENV hash are persistent after the processexits. This can cause unintended issues.Don't count on signals or C<%SIG> for anything.Don't count on filename globbing. Use C<opendir>, C<readdir>, andC<closedir> instead.Don't count on per-program environment variables, or per-program currentdirectories.Don't count on specific values of C<$!>, 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 ENOENT. And don't trust on the values of C<$!>at all except immediately after a failed system call.=head2 Command names versus file pathnamesDon't assume that the name used to invoke a command or program withC<system> or C<exec> 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 "internal" commands that are built-in to theshell or OS and while these commands can be invoked, there is nocorresponding file. Second, some operating systems (e.g., Cygwin,DJGPP, OS/2, and VOS) have required suffixes for executable files;these suffixes are generally permitted on the command name but are notrequired. Thus, a command like "perl" might exist in a file named"perl", "perl.exe", or "perl.pm", depending on the operating system.The variable "_exe" in the Config module holds the executable suffix,if any. Third, the VMS port carefully sets up $^X and$Config{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 VMSfile name.To convert $^X to a file pathname, taking account of the requirementsof the various operating system possibilities, say: use Config; $thisperl = $^X; if ($^O ne 'VMS') {$thisperl .= $Config{_exe} unless $thisperl =~ m/$Config{_exe}$/i;}To convert $Config{perlpath} to a file pathname, say: use Config; $thisperl = $Config{perlpath}; if ($^O ne 'VMS') {$thisperl .= $Config{_exe} unless $thisperl =~ m/$Config{_exe}$/i;}=head2 NetworkingDon't assume that you can reach the public Internet.Don't assume that there is only one way to get through firewallsto the public Internet.Don't assume that you can reach outside world through any other portthan 80, or some web proxy. ftp is blocked by many firewalls.Don't assume that you can send email by connecting to the local SMTP port.Don'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.Don't assume that the host has only one network card, or that itcan't bind to many virtual IP addresses.Don't assume a particular network device name.Don't assume a particular set of ioctl()s will work.Don't assume that you can ping hosts and get replies.Don't assume that any particular port (service) will respond.Don't assume that Sys::Hostname (or any other API 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 DHCP and NAT-- the hostname you get back might not be veryuseful.All the above "don't":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.=head2 Interprocess Communication (IPC)In general, don't directly access the system in code meant to beportable. That means, no C<system>, C<exec>, C<fork>, C<pipe>,C<``>, C<qx//>, C<open> with a C<|>, nor any of the other thingsthat makes being a perl hacker worth being.Commands 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 I<netstat -a>, you probably don't expect it to run on both Unix and CP/M.)One especially common bit of Perl code is opening a pipe to B<sendmail>: open(MAIL, '|/usr/lib/sendmail -t') or die "cannot fork sendmail: $!";This 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 CPAN that dealwith it. Mail::Mailer and Mail::Send in the MailTools distribution arecommonly used, and provide several mailing methods, including mail,sendmail, and direct SMTP (via Net::SMTP) if a mail transfer agent isnot available. Mail::Sendmail is a standalone module that providessimple, platform-independent mailing.The Unix System V IPC (C<msg*(), sem*(), shm*()>) is not availableeven on all Unix platforms.Do not use either the bare result of C<pack("N", 10, 20, 30, 40)> orbare v-strings (such as C<v10.20.30.40>) to represent IPv4 addresses:both forms just pack the four bytes into network order. That thiswould be equal to the C language C<in_addr> struct (which is what thesocket code internally uses) is not guaranteed. To be portable usethe routines of the Socket extension, such as C<inet_aton()>,C<inet_ntoa()>, and C<sockaddr_in()>.The 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).=head2 External Subroutines (XS)XS code can usually be made to work with any platform, but dependentlibraries, header files, etc., might not be readily available orportable, or the XS 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 XS code is portable, too.A different type of portability issue arises when writing XS code:availability of a C compiler on the end-user's system. C bringswith it its own portability issues, and writing XS code will exposeyou to some of those. Writing purely in Perl is an easier way toachieve portability.=head2 Standard ModulesIn general, the standard modules work across platforms. Notableexceptions are the CPAN module (which currently makes connections to externalprograms that may not be available), platform-specific modules (likeExtUtils::MM_VMS), and DBM modules.There is no one DBM 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.The good news is that at least some DBM 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 DBM module. See L<AnyDBM_File> for more details.=head2 Time and DateThe system's notion of time of day and calendar date is controlled inwidely different ways. Don't assume the timezone is stored in C<$ENV{TZ}>,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 MST 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 UTC, or the POSIX timezoneformat.Don't assume that the epoch starts at 00:00:00, January 1, 1970,because that is OS- and implementation-specific. It is better tostore a date in an unambiguous representation. The ISO 8601 standarddefines YYYY-MM-DD as the date format, or YYYY-MM-DDTHH-MM-SS(that's a literal "T" separating the date from the time).Please do use the ISO 8601 instead of making us to guess whatdate 02/03/04 might be. ISO 8601 even sorts nicely as-is.A text representation (like "1987-12-18") can be easily convertedinto an OS-specific value using a module like Date::Parse.An array of values, such as those returned by C<localtime>, can beconverted to an OS-specific representation using Time::Local.When calculating specific times, such as for tests in time or date modules,it may be appropriate to calculate an offset for the epoch.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?