📄 ch25_01.htm
字号:
<html><head><title>Portable Perl (Programming Perl)</title><!-- STYLESHEET --><link rel="stylesheet" type="text/css" href="../style/style1.css"><!-- METADATA --><!--Dublin Core Metadata--><meta name="DC.Creator" content=""><meta name="DC.Date" content=""><meta name="DC.Format" content="text/xml" scheme="MIME"><meta name="DC.Generator" content="XSLT stylesheet, xt by James Clark"><meta name="DC.Identifier" content=""><meta name="DC.Language" content="en-US"><meta name="DC.Publisher" content="O'Reilly & Associates, Inc."><meta name="DC.Source" content="" scheme="ISBN"><meta name="DC.Subject.Keyword" content=""><meta name="DC.Title" content="Portable Perl"><meta name="DC.Type" content="Text.Monograph"></head><body><!-- START OF BODY --><!-- TOP BANNER --><img src="gifs/smbanner.gif" usemap="#banner-map" border="0" alt="Book Home"><map name="banner-map"><AREA SHAPE="RECT" COORDS="0,0,466,71" HREF="index.htm" ALT="Programming Perl"><AREA SHAPE="RECT" COORDS="467,0,514,18" HREF="jobjects/fsearch.htm" ALT="Search this book"></map><!-- TOP NAV BAR --><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch24_05.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="part4.htm">Part 4: Perl as Culture</a></td><td align="right" valign="top" width="172"><a href="ch25_02.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr></table></div><hr width="515" align="left"><!-- SECTION BODY --><h1 class="chapter">Chapter 25. Portable Perl</h1><div class="htmltoc"><h4 class="tochead">Contents:</h4><p><a href="ch25_01.htm">Newlines</a><br><a href="ch25_02.htm">Endianness and Number Width</a><br><a href="ch25_03.htm">Files and Filesystems</a><br><a href="ch25_04.htm">System Interaction</a><br><a href="ch25_05.htm">Interprocess Communication (IPC)</a><br><a href="ch25_06.htm">External Subroutines (XS)</a><br><a href="ch25_07.htm">Standard Modules</a><br><a href="ch25_08.htm">Dates and Times</a><br><a href="ch25_09.htm">Internationalization</a><br><a href="ch25_10.htm">Style</a><br></p></div><a name="INDEX-4310"></a><a name="INDEX-4311"></a><a name="INDEX-4312"></a><p>A world with only one operating system makes portability easy, andlife boring. We prefer a larger genetic pool of operating systems, aslong as the ecosystem doesn't divide too cleanly into predators andprey. Perl runs on dozens of operating systems, and because Perlprograms aren't platform dependent, the same program can run on allof those systems without modification.</p><p>Well, almost. Perl tries to give the programmer as many features aspossible, but if you make use of features particular to a certainoperating system, you'll necessarily reduce the portability of yourprogram to other systems. In this section, we'll provide someguidelines for writing portable Perl code. Once you make a decisionabout how portable you want to be, you'll know where the lines aredrawn, and you can stay within them.</p><p>Looking at it another way, writing portable code is usually aboutwillfully limiting your available choices. Naturally, it takesdiscipline and sacrifice to do that, two traits that Perl programmersmight be unaccustomed to.</p><p>Be aware that not all Perl programs have to be portable. There is noreason not to use Perl to glue Unix tools together, or to prototype aMacintosh application, or to manage the Windows registry. If it makessense to sacrifice portability, go ahead.<a href="#FOOTNOTE-1">[1]</a></p><blockquote class="footnote"><a name="FOOTNOTE-1"></a><p>[1] Not everyconversation has to be cross-culturally correct. Perl tries to giveyou at least one way to do the Right Thing but doesn't try to force iton you rigidly. In this respect, Perl more closely resembles yourmother tongue than a nanny's tongue.</p></blockquote><p>In general, note that the notions of a user ID, a "home" directory,and even the state of being logged in will exist only on multi-userplatforms.</p><p><a name="INDEX-4313"></a>The special <tt class="literal">$^O</tt> variable tells you what operating system your Perlwas built on. This is provided to speed up code that would otherwisehave to <tt class="literal">use Config</tt> to get the same information via<tt class="literal">$Config{osname}</tt>. (Even if you've pulled in <tt class="literal">Config</tt>for other reasons, it still saves you the price of a tied-hash lookup.)</p><p><a name="INDEX-4314"></a>To get more detailed information about the platform, you can look atthe rest of the information in the <tt class="literal">%Config</tt> hash, which is madeavailable by the standard <tt class="literal">Config</tt> module. For example, to checkwhether the platform has the <tt class="literal">lstat</tt> call, you can check<tt class="literal">$Config{d_lstat}</tt>. See <tt class="literal">Config</tt>'s online documentation for a fulldescription of available variables, and the <em class="emphasis">perlport</em> manpagefor a listing of the behavior of Perl built-in functions on differentplatforms. Here are the Perl functions whose behavior varies the mostacross platforms:<a name="INDEX-4315"></a></p><p><tt class="literal">-</tt><em class="replaceable">X</em> (file tests),<tt class="literal">accept</tt>, <tt class="literal">alarm</tt>,<tt class="literal">bind</tt>, <tt class="literal">binmode</tt>,<tt class="literal">chmod</tt>, <tt class="literal">chown</tt>,<tt class="literal">chroot</tt>, <tt class="literal">connect</tt>,<tt class="literal">crypt</tt>, <tt class="literal">dbmclose</tt>,<tt class="literal">dbmopen</tt>, <tt class="literal">dump</tt>,<tt class="literal">endgrent</tt>, <tt class="literal">endhostent</tt>,<tt class="literal">endnetent</tt>, <tt class="literal">endprotoent</tt>,<tt class="literal">endpwent</tt>, <tt class="literal">endservent</tt>,<tt class="literal">exec</tt>, <tt class="literal">fcntl</tt>,<tt class="literal">fileno</tt>, <tt class="literal">flock</tt>,<tt class="literal">fork</tt>, <tt class="literal">getgrent</tt>,<tt class="literal">getgrgid</tt>, <tt class="literal">getgrnam</tt>,<tt class="literal">gethostbyaddr</tt>, <tt class="literal">gethostbyname</tt>,<tt class="literal">gethostent</tt>, <tt class="literal">getlogin</tt>,<tt class="literal">getnetbyaddr</tt>, <tt class="literal">getnetbyname</tt>,<tt class="literal">getnetent</tt>, <tt class="literal">getpeername</tt>,<tt class="literal">getpgrp</tt>, <tt class="literal">getppid</tt>,<tt class="literal">getpriority</tt>, <tt class="literal">getprotobyname</tt>,<tt class="literal">getprotobynumber</tt>, <tt class="literal">getprotoent</tt>,<tt class="literal">getpwent</tt>, <tt class="literal">getpwnam</tt>,<tt class="literal">getpwuid</tt>, <tt class="literal">getservbyport</tt>,<tt class="literal">getservent</tt>, <tt class="literal">getservbyname</tt>,<tt class="literal">getsockname</tt>, <tt class="literal">getsockopt</tt>,<tt class="literal">glob</tt>, <tt class="literal">ioctl</tt>,<tt class="literal">kill</tt>, <tt class="literal">link</tt>,<tt class="literal">listen</tt>, <tt class="literal">lstat</tt>,<tt class="literal">msgctl</tt>, <tt class="literal">msgget</tt>,<tt class="literal">msgrcv</tt>, <tt class="literal">msgsnd</tt>,<tt class="literal">open</tt>, <tt class="literal">pipe</tt>,<tt class="literal">qx</tt>, <tt class="literal">readlink</tt>,<tt class="literal">readpipe</tt>, <tt class="literal">recv</tt>,<tt class="literal">select</tt>, <tt class="literal">semctl</tt>,<tt class="literal">semget</tt>, <tt class="literal">semop</tt>,<tt class="literal">send</tt>, <tt class="literal">sethostent</tt>,<tt class="literal">setgrent</tt>, <tt class="literal">setnetent</tt>,<tt class="literal">setpgrp</tt>, <tt class="literal">setpriority</tt>,<tt class="literal">setprotoent</tt>, <tt class="literal">setpwent</tt>,<tt class="literal">setservent</tt>, <tt class="literal">setsockopt</tt>,<tt class="literal">shmctl</tt>, <tt class="literal">shmget</tt>,<tt class="literal">shmread</tt>, <tt class="literal">shmwrite</tt>,<tt class="literal">shutdown</tt>, <tt class="literal">socket</tt>,<tt class="literal">socketpair</tt>, <tt class="literal">stat</tt>,<tt class="literal">symlink</tt>, <tt class="literal">syscall</tt>,<tt class="literal">sysopen</tt>, <tt class="literal">system</tt>,<tt class="literal">times</tt>, <tt class="literal">truncate</tt>,<tt class="literal">umask</tt>, <tt class="literal">utime</tt>,<tt class="literal">wait</tt>, <tt class="literal">waitpid</tt></p><h2 class="sect1">25.1. Newlines</h2><a name="INDEX-4316"></a><a name="INDEX-4317"></a><a name="INDEX-4318"></a><a name="INDEX-4319"></a><a name="INDEX-4320"></a><a name="INDEX-4321"></a><p>On most operating systems, lines in files are terminated by one or twocharacters that signal the end of the line. The characters vary fromsystem to system. Unix traditionally uses <tt class="literal">\012</tt> (that is, the octal12 character in ASCII), one type of DOSish I/O uses <tt class="literal">\015\012</tt>, andMacs uses <tt class="literal">\015</tt>. Perl uses <tt class="literal">\n</tt> to represent a "logical" newline,regardless of platform. In MacPerl, <tt class="literal">\n</tt> always means <tt class="literal">\015</tt>. InDOSish Perls, <tt class="literal">\n</tt> usually means <tt class="literal">\012</tt>, but when accessing a filein "text mode", it is translated to (or from) <tt class="literal">\015\012</tt>, dependingon whether you're reading or writing. Unix does the same thing onterminals in canonical mode. <tt class="literal">\015\012</tt> is commonly referred to asCRLF.</p><p>Because DOS distinguishes between text files and binary files, DOSishPerls have limitations when using <tt class="literal">seek</tt> and<tt class="literal">tell</tt> on a file in "text mode". For best results,only <tt class="literal">seek</tt> to locations obtained from<tt class="literal">tell</tt>. If you use Perl's built-in<tt class="literal">binmode</tt> function on the filehandle, however, youcan usually <tt class="literal">seek</tt> and <tt class="literal">tell</tt> withimpunity.</p><p>A common misconception in socket programming is that<tt class="literal">\n</tt> will be <tt class="literal">\012</tt> everywhere.In many common Internet protocols, <tt class="literal">\012</tt> and<tt class="literal">\015</tt> are specified, and the values of Perl's<tt class="literal">\n</tt> and <tt class="literal">\r</tt> are not reliable sincethey vary from system to system:<blockquote><pre class="programlisting">print SOCKET "Hi there, client!\015\012"; # rightprint SOCKET "Hi there, client!\r\n"; # wrong</pre></blockquote>However, using <tt class="literal">\015\012</tt> (or<tt class="literal">\cM\cJ</tt>, or <tt class="literal">\x0D\x0A</tt>, or even<tt class="literal">v13.10</tt>) can be tedious and unsightly, as well asconfusing to those maintaining the code. The<tt class="literal">Socket</tt> module supplies some Right Things for thosewho want them:<blockquote><pre class="programlisting">use Socket qw(:DEFAULT :crlf);print SOCKET "Hi there, client!$CRLF" # right</pre></blockquote>When reading from a socket, remember that the default input recordseparator <tt class="literal">$/</tt> is <tt class="literal">\n</tt>, which means you have to do some extra workif you're not sure what you'll be seeing across the socket. Robustsocket code should recognize either <tt class="literal">\012</tt> or <tt class="literal">\015\012</tt> as end ofline:<blockquote><pre class="programlisting">use Socket qw(:DEFAULT :crlf);local ($/) = LF; # not needed if $/ is already \012while (<SOCKET>) { s/$CR?$LF/\n/; # replace LF or CRLF with logical newline}</pre></blockquote>Similarly, code that returns text data--such as a subroutine thatfetches a web page--should often translate newlines. A single line ofcode will often suffice:<blockquote><pre class="programlisting">$data =~ s/\015?\012/\n/g;return $data;</pre></blockquote></p><a name="INDEX-4369"></a><a name="INDEX-4370"></a><a name="INDEX-4371"></a><!-- BOTTOM NAV BAR --><hr width="515" align="left"><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch24_05.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0"></a></td><td align="right" valign="top" width="172"><a href="ch25_02.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">24.5. Program Generation</td><td align="center" valign="top" width="171"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0"></a></td><td align="right" valign="top" width="172">25.2. Endianness and Number Width</td></tr></table></div><hr width="515" align="left"><!-- LIBRARY NAV BAR --><img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p><font size="-1"><a href="copyrght.htm">Copyright © 2001</a> O'Reilly & Associates. All rights reserved.</font></p><map name="library-map"> <area shape="rect" coords="2,-1,79,99" href="../index.htm"><area shape="rect" coords="84,1,157,108" href="../perlnut/index.htm"><area shape="rect" coords="162,2,248,125" href="../prog/index.htm"><area shape="rect" coords="253,2,326,130" href="../advprog/index.htm"><area shape="rect" coords="332,1,407,112" href="../cookbook/index.htm"><area shape="rect" coords="414,2,523,103" href="../sysadmin/index.htm"></map><!-- END OF BODY --></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -