📄 ch06_04.htm
字号:
<html><head><title>Output to Standard Output (Learning Perl, 3rd Edition)</title><link rel="stylesheet" type="text/css" href="../style/style1.css" /><meta name="DC.Creator" content="Randal L. Schwartz and Tom Phoenix" /><meta name="DC.Format" content="text/xml" scheme="MIME" /><meta name="DC.Language" content="en-US" /><meta name="DC.Publisher" content="O'Reilly & Associates, Inc." /><meta name="DC.Source" scheme="ISBN" content="0596001320L" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="Learning Perl, 3rd Edition" /><meta name="DC.Type" content="Text.Monograph" /></head><body bgcolor="#ffffff"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Learning Perl, 3rd Edition" /><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch06_03.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"></a></td><td align="right" valign="top" width="228"><a href="ch06_05.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr></table></div><h2 class="sect1">6.4. Output to Standard Output</h2><p><a name="INDEX-451" /><a name="INDEX-452" /><a name="INDEX-453" />The<tt class="literal">print</tt><a name="INDEX-454" />operator takes a list of values and sends each item (as a string, ofcourse) to standard output in turn, one after another. Itdoesn't add any extra characters before, after, or in betweenthe items;<a href="#FOOTNOTE-152">[152]</a> if you want spaces between items and a newline at theend, you have to say so:</p><blockquote class="footnote"> <a name="FOOTNOTE-152" /><p>[152]Well, it doesn't add anything extra<em class="emphasis">by default</em>, but this default (like so manyothers in Perl) may be changed. Changing these defaults will likelyconfuse your maintenance programmer, though, so avoid doing so exceptin small, quick-and-dirty programs, or (rarely) in a small section ofa normal program. See the <em class="emphasis">perlvar</em>manpage to learn about changing the defaults.</p></blockquote><blockquote><pre class="code">$name = "Larry Wall";print "Hello there, $name, did you know that 3+4 is ", 3+4, "?\n";</pre></blockquote><p>Of course, that means that there's a difference betweenprinting an<a name="INDEX-455" />array and interpolating an array:</p><blockquote><pre class="code">print @array; # print a list of itemsprint "@array"; # print a string (containing an interpolated array)</pre></blockquote><p>That first <tt class="literal">print</tt> statement will print a list ofitems, one after another, with no spaces in between. The second onewill print exactly one item, which is the string you get byinterpolating <tt class="literal">@array</tt> into the emptystring -- that is, it prints the contents of<tt class="literal">@array</tt>, separated by spaces.<a href="#FOOTNOTE-153">[153]</a> So, if <tt class="literal">@array</tt> holds<tt class="literal">qw/</tt> <tt class="literal">fred barney</tt><tt class="literal">betty</tt> <tt class="literal">/</tt>,<a href="#FOOTNOTE-154">[154]</a> the first one prints<tt class="literal">fredbarneybetty</tt>, while the second prints<tt class="literal">fred</tt> <tt class="literal">barney betty</tt> separated byspaces.</p><blockquote class="footnote"> <a name="FOOTNOTE-153" /><p>[153]Yes,the spaces are another default; see the<em class="emphasis">perlvar</em>manpage again.</p></blockquote><blockquote class="footnote"> <a name="FOOTNOTE-154" /><p>[154]Youknow that we mean a three-element list here, right? This is just Perlnotation.</p> </blockquote><p>But before you decide to always use the second form, imagine that<tt class="literal">@array</tt> is a list of unchomped lines of input. Thatis, imagine that each of its strings has a trailing newlinecharacter. Now, the first <tt class="literal">print</tt> statement prints<tt class="literal">fred</tt>, <tt class="literal">barney</tt>, and<tt class="literal">betty</tt> on three separate lines. But the second oneprints this:</p><blockquote><pre class="code">fred barney betty</pre></blockquote><p>Do you see where the spaces come from? Perl is interpolating anarray, so it puts spaces between the elements. So, we get the firstelement of the array (<tt class="literal">fred</tt> and a newlinecharacter), then a space, then the next element of the array(<tt class="literal">barney</tt> and a newline character), then a space,then the last element of the array (<tt class="literal">betty</tt> and anewline character). The result is that the lines seem to have becomeindented, except for the first one. Every week or two, a messageappears on the newsgroup <em class="emphasis">comp.lang.perl.misc</em>with a subject line something like:</p><blockquote class="simplelist"><p>Perl indents everything after the first line </p></blockquote><p>Without even reading the message, we can immediately see that theprogram used <a name="INDEX-456" />double quotes around an array containingunchomped strings. "Did you perhaps put an array of unchompedstrings inside double quotes?" we ask, and the answer is alwaysyes.</p><p>Generally, if your strings contain <a name="INDEX-457" /><a name="INDEX-458" />newlines, you simply want to print them,after all:</p><blockquote><pre class="code">print @array;</pre></blockquote><p>But if they don't contain newlines, you'll generally wantto add one at the end:</p><blockquote><pre class="code">print "@array\n";</pre></blockquote><p>So, if you're using the quote marks, you'll be(generally) adding the <tt class="literal">\n</tt> at the end of the stringanyway; this should help you to remember which is which.</p><p>It's normal for your program's output to be<em class="firstterm">buffered</em><a name="INDEX-459" /><a name="INDEX-460" />.That is, instead of sending out every little bit of output at once,it'll be saved until there's enough to bother with.That's because if (for example) the output were going to besaved on disk, it would be (relatively) slow and inefficient to spinthe disk every time that one or two characters need to be added tothe file. Generally, then, the output will go into a buffer that is<em class="firstterm">flushed</em><a name="INDEX-461" /><a name="INDEX-462" /> (that is, actually written to disk, orwherever) only when the buffer gets full, or when the output isotherwise finished (such as at the end of runtime). Usually,that's what you want.</p><p>But if you (or a program) may be waiting impatiently for the output,you may wish to take that performance hit and flush the output buffereach time you <tt class="literal">print</tt>. See the Perl manpages formore information on controlling buffering in that case.</p><p>Since <tt class="literal">print</tt> is looking for a list of strings toprint, its arguments are evaluated in list context. Since the diamondoperator (as a special kind of line-input operator) will return alist of lines in a list context, these can work well together:</p><blockquote><pre class="code">print <>; # source code for 'cat'print sort <>; # source code for 'sort'</pre></blockquote><p>Well, to be fair, the standard Unix commands <i class="command">cat</i>and <i class="command">sort</i> do have some additional functionalitythat these replacements lack. But you can't beat them for theprice! You can now re-implement all of your standard Unix utilitiesin Perl, and painlessly port them to any machine that has Perl,whether that machine is running Unix or not. And you can be sure thatthe programs on every different type of machine will neverthelesshave the same behavior.<a href="#FOOTNOTE-155">[155]</a></p><blockquote class="footnote"> <a name="FOOTNOTE-155" /><p>[155]In fact, there was even anendeavor started, called the PPT (Perl Power Tools) project, whosegoal is to implement all of the classic Unix utilities in Perl. Theyactually completed nearly all the utilities (and most of the games!),but got bogged down when they got to reimplementing the shell. ThePPT project has been helpful because it has made these standardutilities available on many non-Unix machines. </p> </blockquote><p>What might not be obvious is that<tt class="literal">print</tt><a name="INDEX-463" /><a name="INDEX-464" />has optional parentheses, which can sometimes cause confusion.Remember the rule that parentheses in Perl may always be omitted,except when doing so would change the meaning of a statement. So,here are two ways to print the same thing:</p><blockquote><pre class="code">print("Hello, world!\n");print "Hello, world!\n";</pre></blockquote><p>So far, so good. But another rule in Perl is that if the invocationof <tt class="literal">print</tt> <em class="emphasis">looks</em> like afunction call, then it <em class="emphasis">is</em> a function call.It's a simple rule, but what does it mean for something to looklike a function call?</p><p>In a function call, there's a function nameimmediately<a href="#FOOTNOTE-156">[156]</a> followed by parentheses around thefunction's arguments, like this:</p><blockquote class="footnote"> <a name="FOOTNOTE-156" /><p>[156]We say "immediately" herebecause Perl won't permit a newline character between thefunction name and the opening parenthesis in this kind of functioncall. If there is a newline there, Perl sees your code as making alist operator, rather than a function call. This is the kind ofpiddling technical detail that we mention only for completeness. Ifyou're terminally curious, see the full story in themanpages.</p> </blockquote><blockquote><pre class="code">print (2+3);</pre></blockquote><p>That looks like a <a name="INDEX-465" />function call, so it is a function call. Itprints <tt class="literal">5</tt>, but then it returns a value like anyother function. The return value of <tt class="literal">print</tt> is atrue or false value, indicating the success of the print. It nearlyalways succeeds, unless you get some I/O error, so the<tt class="literal">$result</tt> in the following statement will normallybe <tt class="literal">1</tt>:</p><blockquote><pre class="code">$result = print("hello world!\n");</pre></blockquote><p>But what if you used the result in some other way? Let'ssuppose you decide to multiply the return value times four:</p><blockquote><pre class="code">print (2+3)*4; # Oops!</pre></blockquote><p>When Perl sees this line of code, it prints <tt class="literal">5</tt>,just as you asked. Then it takes the return value from<tt class="literal">print</tt>, which is <tt class="literal">1</tt>, andmultiplies that times <tt class="literal">4</tt>. It then throws away theproduct, wondering why you didn't tell it to do something elsewith it. And at this point, someone looking over your shoulder says,"Hey, Perl can't do math! That should have printed<tt class="literal">20</tt>, rather than <tt class="literal">5</tt>!"</p><p>This is the problem with allowing the parentheses to be optional;sometimes we humans forget where the parentheses really belong. Whenthere are no parentheses, <tt class="literal">print</tt> is a listoperator, printing all of the items in the following list;that's generally what you'd expect. But when the firstthing after <tt class="literal">print</tt> is a left parenthesis,<tt class="literal">print</tt> is a function call, and it will print onlywhat's found inside the parentheses. Since that line hadparentheses, it's the same to Perl as if you'd said this:</p><blockquote><pre class="code">( print(2+3) ) * 4; # Oops!</pre></blockquote><p>Fortunately, Perl itself can almost always help you with this, if youask for warnings -- so use <tt class="literal">-w</tt>, at least duringprogram development and debugging.</p><p>Actually, this rule -- "If it looks like a function call, itis a function call" -- applies to all listfunctions<a href="#FOOTNOTE-157">[157]</a> in Perl, notjust to <tt class="literal">print</tt>. It's just that you'remost likely to notice it with <tt class="literal">print</tt>. If<tt class="literal">print</tt> (or another function name) is followed byan open parenthesis, make sure that the corresponding closeparenthesis comes after <em class="emphasis">all</em> of the arguments tothat function.<a name="INDEX-466" /> </p><blockquote class="footnote"> <a name="FOOTNOTE-157" /><p>[157]Functions that take zero or one argumentsdon't suffer from this problem.</p> </blockquote><hr width="684" align="left" /><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch06_03.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"><img alt="Home" border="0" src="../gifs/txthome.gif" /></a></td><td align="right" valign="top" width="228"><a href="ch06_05.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">6.3. The Invocation Arguments</td><td align="center" valign="top" width="228"><a href="index/index.htm"><img alt="Book Index" border="0" src="../gifs/index.gif" /></a></td><td align="right" valign="top" width="228">6.5. Formatted Output with printf</td></tr></table></div><hr width="684" align="left" /><img alt="Library Navigation Links" border="0" src="../gifs/navbar.gif" usemap="#library-map" /><p><p><font size="-1"><a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font></p><map name="library-map"><area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -