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

📄 ch03_08.htm

📁 by Randal L. Schwartz and Tom Phoenix ISBN 0-596-00132-0 Third Edition, published July 2001. (See
💻 HTM
字号:
<html><head><title>Scalar and List Context (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="ch03_07.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="ch03_09.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr></table></div><h2 class="sect1">3.8. Scalar and List Context</h2><p><a name="INDEX-300" /><a name="INDEX-301" />This <a name="INDEX-302" />is the most important section in thischapter. In fact, it's the most important section in the entirebook. In fact, it wouldn't be an exaggeration to say that yourentire career in using Perl will depend upon understanding thissection. So if you've gotten away with skimming the text up tothis point, this is where you should really pay attention.</p><p>That's not to say that this section is in any way difficult tounderstand. It's actually a simple idea: a given expression maymean different things depending upon where it appears. This isnothing new to you; it happens all the time in natural languages. Forexample, in English,<a href="#FOOTNOTE-83">[83]</a>suppose someone asked you what the word "read"<a href="#FOOTNOTE-84">[84]</a> means. It has different meanings depending on howit's used. You can't identify the meaning, until you knowthe <em class="emphasis">context</em>.</p><blockquote class="footnote"> <a name="FOOTNOTE-83" /><p>[83]If you aren't a nativespeaker of English, this analogy may not be obvious to you. Butcontext sensitivity happens in every spoken language, so you may beable to think of an example in your own language.</p> </blockquote><blockquote class="footnote"><a name="FOOTNOTE-84" /><p>[84]Or maybe they were asking what the word "red"means, if they were speaking rather than writing a book. It'sambiguous either way. As Douglas Hofstadter said, no language canexpress every thought unambiguously, especially this one.</p></blockquote><p>The <em class="emphasis">context</em><a name="INDEX-303" /><a name="INDEX-304" /> refers to where anexpression is found. As Perl is parsing your expressions, it alwaysexpects either a scalar value or a list value.<a href="#FOOTNOTE-85">[85]</a> What Perl expects is called the context of theexpression.<a href="#FOOTNOTE-86">[86]</a></p><blockquote class="footnote"><a name="FOOTNOTE-85" /><p>[85]Unless, of course, Perl is expecting something else entirely.There are other contexts that aren't covered here. In fact,nobody knows how many contexts Perl uses; the biggest brains in allof Perl haven't agreed on an answer to that yet.</p></blockquote><blockquote class="footnote"> <a name="FOOTNOTE-86" /><p>[86]This is no different than whatyou're used to in human languages. If I make a grammaticalmistake, you notice it right away, because you expect certain wordsin places certain. Eventually, you'll read Perl this way, too,but at first you have to think about it.</p> </blockquote><blockquote><pre class="code">5 + <em class="emphasis">something</em>  # The <em class="emphasis">something</em> must be a scalarsort <em class="emphasis">something</em> # The <em class="emphasis">something</em> must be a list</pre></blockquote><p>Even if <em class="emphasis">something</em> is the exactsame sequence of characters, in one case it may give a single, scalarvalue, while in the other, it may give a list.<a href="#FOOTNOTE-87">[87]</a></p><blockquote class="footnote"> <a name="FOOTNOTE-87" /><p>[87]Thelist may be just one element long, of course. It could also be empty,or it could have any number of elements.</p> </blockquote><p>Expressions in Perl always return the appropriate value for theircontext. For example, how about the "name"<a href="#FOOTNOTE-88">[88]</a> of an array. In a list context, itgives the list of elements. But in a scalar context, it returns thenumber of elements in the array:</p><blockquote class="footnote"><a name="FOOTNOTE-88" /><p>[88]Well, the true name of the array<tt class="literal">@people</tt>isjust <tt class="literal">people</tt>. The <tt class="literal">@</tt>-sign is justa qualifier.</p> </blockquote><blockquote><pre class="code">@people = qw( fred barney betty );@sorted = sort @people; # list context: barney, betty, fred$number = 5 + @people;  # scalar context: 5 + 3 gives 8</pre></blockquote><p>Even ordinary assignment (to a scalar or a list) causes differentcontexts:</p><blockquote><pre class="code">@list = @people; # a list of three people$n = @people;    # the number 3</pre></blockquote><p>But please don't jump to the conclusion that scalar contextalways gives the number of elements that would have been returned inlist context. Most list-producing expressions<a href="#FOOTNOTE-89">[89]</a> return something<em class="emphasis">much</em> more interesting than that.</p><blockquote class="footnote"> <a name="FOOTNOTE-89" /><p>[89]Butwith regard to the point of this section, there's no differencebetween a "list-producing" expression and a"scalar-producing" one; any expression can produce a listor a scalar, depending upon context. So when we say"list-producing expressions," we mean expressions thatare typically used in a list context and that therefore mightsurprise you when they're used unexpectedly in a scalar context(like <tt class="literal">reverse</tt> or <tt class="literal">@fred</tt><tt class="literal">)</tt>.</p> </blockquote><a name="lperl3-CHP-3-SECT-8.1" /><div class="sect2"><h3 class="sect2">3.8.1. Using List-Producing Expressions in Scalar Context</h3><p>There are many expressions that would typically be used to produce alist. If you use one in a scalar context, what do you get? See whatthe author of that operation says about it. Usually, that person isLarry, and usually the documentation gives the whole story. In fact,a big part of learning Perl is actually learning how Larrythinks.<a href="#FOOTNOTE-90">[90]</a> Therefore, once you can think like Larry does, you knowwhat Perl should do. But while you're learning, you'llprobably need to look into the documentation.</p><blockquote class="footnote"> <a name="FOOTNOTE-90" /><p>[90]This is only fair, since while writing Perlhe tried to think like you do to predict what you would want!</p></blockquote><p>Some expressions don't have a scalar-context value at all. Forexample, what should <tt class="literal">sort</tt> returnin a scalar context? You wouldn't need to sort a list to countits elements, so until someone implements something else, <tt class="literal">sort</tt> in a scalar context always returns<tt class="literal">undef</tt>.</p><p>Another example is <tt class="literal">reverse</tt>. In alist context, it gives a reversed list. In a scalar context, itreturns a reversed string (or reversing the result of concatenatingall the strings of a list, if given one):</p><blockquote><pre class="code">@backwards = reverse qw/ yabba dabba doo /;   # gives doo, dabba, yabba$backwards = reverse qw/ yabba dabba doo /;   # gives oodabbadabbay</pre></blockquote><p>At first, it's not always obvious whether an expression isbeing used in a scalar or a list context. But, trust us, it <em class="emphasis">will</em> get to be second nature for youeventually.</p><p>Here are some common contexts to start you off:</p><blockquote><pre class="code">$fred = <em class="emphasis">something</em>;            # scalar context@pebbles = <em class="emphasis">something</em>;         # list context($wilma, $betty) = <em class="emphasis">something</em>; # list context($dino) = <em class="emphasis">something</em>;          # still list context!</pre></blockquote><p>Don't be fooled by the one-element list; that last one is alist context, not a scalar one. If you're assigning to a list(no matter the number of elements), it's a list context. Ifyou're assigning to an array, it's a list context.</p><p>Here are some other expressions we've seen, and the contextsthey provide. First, some that provide scalar context to <em class="emphasis">something</em>:</p><blockquote><pre class="code">$fred = <em class="emphasis">something</em>;$fred[3] = <em class="emphasis">something</em>;123 + <em class="emphasis">something</em><em class="emphasis">something</em> + 654if (<em class="emphasis">something</em>) { ... }while (<em class="emphasis">something</em>) { ... }$fred[<em class="emphasis">something</em>] = <em class="emphasis">something</em>;</pre></blockquote><p>And here are some that provide a list context:</p><blockquote><pre class="code">@fred = <em class="emphasis">something</em>;($fred, $barney) = <em class="emphasis">something</em>;($fred) = <em class="emphasis">something</em>;push @fred, <em class="emphasis">something</em>;foreach $fred (<em class="emphasis">something</em>) { ... }sort <em class="emphasis">something</em>reverse <em class="emphasis">something</em>print <em class="emphasis">something</em></pre></blockquote></div><a name="lperl3-CHP-3-SECT-8.2" /><div class="sect2"><h3 class="sect2">3.8.2. Using Scalar-Producing Expressions in List Context</h3><p>Going this direction is straightforward: if an expressiondoesn't normally have a list value, the scalar value isautomatically promoted to make a one-element list:</p><blockquote><pre class="code">@fred = 6 * 7; # gets the one-element list (42)@barney = "hello" . ' ' . "world";</pre></blockquote><p>Well, there's one possible catch:</p><blockquote><pre class="code">@wilma = undef; # OOPS! Gets the one-element list (undef)  # which is not the same as this:@betty = ( );    # A correct way to empty an array</pre></blockquote><p>Since <tt class="literal">undef</tt> is a scalar value,assigning <tt class="literal">undef</tt> to an arraydoesn't clear the array. The better way to do that is to assignan empty list.<a href="#FOOTNOTE-91">[91]</a><a name="INDEX-305" /> </p><blockquote class="footnote"> <a name="FOOTNOTE-91" /><p>[91]Well, in most real-world algorithms,if the variable is declared in the proper scope, it will never needto be explicitly emptied. So this type of assignment is rare inwell-written Perl programs. We'll learn about scoping in thenext chapter.</p> </blockquote></div><a name="lperl3-CHP-3-SECT-8.3" /><div class="sect2"><h3 class="sect2">3.8.3. Forcing Scalar Context</h3><p>On occasion, you may need to force <a name="INDEX-306" />scalarcontext where Perl is expecting a list. In that case, you can use thefake function <tt class="literal">scalar</tt>. It'snot a true function, because it just tells Perl to provide a scalarcontext:</p><blockquote><pre class="code">@rocks = qw( talc quartz jade obsidian );print "How many rocks do you have?\n";print "I have ", @rocks, " rocks!\n";        # WRONG, prints names of rocksprint "I have ", scalar @rocks, " rocks!\n"; # Correct, gives a number</pre></blockquote><p>Oddly enough, there's no corresponding function to force listcontext. It turns out never to be needed. Trust us on this,too.<a name="INDEX-307" /><a name="INDEX-308" /></p></div><hr width="684" align="left" /><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch03_07.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="ch03_09.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">3.7. Perl's Favorite Default: $_</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">3.9. &lt;STDIN&gt; in List Context</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 + -