⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch04_04.htm

📁 by Randal L. Schwartz and Tom Phoenix ISBN 0-596-00132-0 Third Edition, published July 2001. (See
💻 HTM
字号:
<html><head><title>Return Values (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 &amp; 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="ch04_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="ch04_05.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr></table></div><h2 class="sect1">4.4. Return Values</h2><p><a name="INDEX-324" />The subroutine is always invoked as partof an expression, even if the result of the expression isn'tbeing used. When we invoked <tt class="literal">&amp;marine</tt> earlier,we were calculating the value of the expression containing theinvocation, but then throwing away the result.</p><p>Many times, we'll call a subroutine and actually do somethingwith the result. This means that we'll be paying attention tothe <em class="emphasis">return value</em> of the subroutine. All Perlsubroutines have a return value -- there's no distinctionbetween those that return values and those that don't. Not allPerl subroutines have a <em class="emphasis">useful</em> return value,however.</p><p>Since all Perl subroutines can be called in a way that needs a returnvalue, it'd be a bit wasteful to have to declare special syntaxto "return" a particular value for the majority of thecases. So Larry made it simple. Every subroutine is chugging along,calculating values as part of its series of actions. Whatevercalculation is <em class="emphasis">last</em> performed in a subroutine is<em class="emphasis">automatically</em> also the return value.</p><p>For example, let's define this subroutine:</p><blockquote><pre class="code">sub sum_of_fred_and_barney {  print "Hey, you called the sum_of_fred_and_barney subroutine!\n";  $fred + $barney;  # That's the return value}</pre></blockquote><p>The last expression evaluated in the body of this subroutine is thesum of <tt class="literal">$fred</tt> and <tt class="literal">$barney</tt>, sothe sum of <tt class="literal">$fred</tt> and <tt class="literal">$barney</tt>will be the return value. Here's that in action:</p><blockquote><pre class="code">$fred = 3;$barney = 4;$c = &amp;sum_of_fred_and_barney; # $c gets 7print "\$c is $c.\n";$d = 3 * &amp;sum_of_fred_and_barney; # $d gets 21print "\$d is $d.\n";</pre></blockquote><p>That code will produce this output:</p><blockquote><pre class="code">Hey, you called the sum_of_fred_and_barney subroutine!$c is 7.Hey, you called the sum_of_fred_and_barney subroutine!$d is 21.</pre></blockquote><p>That <tt class="literal">print</tt> statement is just a debugging aid, sothat we can see that we called the subroutine. You'd take itout when the program is finished. But suppose you added another lineto the end of the code, like this:</p><blockquote><pre class="code">sub sum_of_fred_and_barney {  print "Hey, you called the sum_of_fred_and_barney subroutine!\n";  $fred + $barney;  # That's not really the return value!  print "Hey, I'm returning a value now!\n"; # Oops!}</pre></blockquote><p>In this example, the last expression evaluated is not the addition;it's the <tt class="literal">print</tt> statement. Its return valuewill normally be <tt class="literal">1</tt>, meaning "printing wassuccessful,"<a href="#FOOTNOTE-104">[104]</a>but that's not the return value we actually wanted. So becareful when adding additional code to a subroutine to ensure thatthe last expression <em class="emphasis">evaluated</em> will be thedesired return value.</p><blockquote class="footnote"> <a name="FOOTNOTE-104" /><p>[104]The return value of<tt class="literal">print </tt>is true for a successful operation andfalse for a failure. We'll see how to determine the kind offailure later in <a href="ch11_01.htm">Chapter 11, "Filehandles and File Tests"</a>. </p> </blockquote><p>So, what happened to the sum of <tt class="literal">$fred</tt> and<tt class="literal">$barney</tt> in that subroutine? We didn't put itanywhere, so Perl discarded it. If you had requested warnings, Perl(noticing that there's nothing useful about adding twovariables and discarding the result) would likely warn you aboutsomething like "a useless use of addition in a voidcontext." The term <em class="firstterm">voidcontext</em><a name="INDEX-325" /><a name="INDEX-326" />is just a fancy of saying that the answer isn't being stored ina variable or used by another function.</p><p>"The last expression evaluated" really means the lastexpression <em class="emphasis">evaluated</em>, rather than the last lineof text. For example, this subroutine returns the larger value of<tt class="literal">$fred</tt> or <tt class="literal">$barney</tt>:</p><blockquote><pre class="code">sub larger_of_fred_or_barney {  if ($fred &gt; $barney) {    $fred;  } else {    $barney;  }}</pre></blockquote><p>The last expression evaluated is the single <tt class="literal">$fred</tt>or <tt class="literal">$barney</tt>, which becomes the return value. Wewon't know whether the return value will be<tt class="literal">$fred</tt> or <tt class="literal">$barney</tt> until we seewhat those variables hold at runtime.</p><p>A subroutine can also return a list of values when evaluated in a<a name="INDEX-327" />list context.<a href="#FOOTNOTE-105">[105]</a> Suppose you wanted to get a range of numbers (as from therange operator, <tt class="literal">..</tt>), except that you want to beable to count down as well as up. The range operator only countsupwards, but that's easily fixed:</p><blockquote class="footnote"> <a name="FOOTNOTE-105" /><p>[105]You candetect whether a subroutine is being evaluated in a scalar or listcontext using the <tt class="literal">wantarray</tt><a name="INDEX-328" />function, which lets you easily writesubroutines with specific list or scalar context values.</p></blockquote><blockquote><pre class="code">sub list_from_fred_to_barney {  if ($fred &lt; $barney) {    # Count upwards from $fred to $barney    $fred..$barney;  } else {    # Count downwards from $fred to $barney    reverse $barney..$fred;  }}$fred = 11;$barney = 6;@c = &amp;list_from_fred_to_barney; # @c gets (11, 10, 9, 8, 7, 6)</pre></blockquote><p>In this case, the range operator gives us the list from<tt class="literal">6</tt> to <tt class="literal">11</tt>, then<tt class="literal">reverse</tt> reverses the list, so that it goes from<tt class="literal">$fred</tt> (<tt class="literal">11</tt>) to<tt class="literal">$barney</tt> (<tt class="literal">6</tt>), just as we wanted.</p><p>These are all rather trivial examples. It gets better when we canpass values that are different for each invocation into a subroutineinstead of relying on global variables. In fact, that's comingright up.<a name="INDEX-329" /> </p><hr width="684" align="left" /><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch04_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="ch04_05.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">4.3. Invoking a Subroutine</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">4.5. Arguments</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 &copy; 2002</a> O'Reilly &amp; 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 + -