📄 ch02_07.htm
字号:
<html><head><title>Context (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="Context"><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="ch02_06.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="ch02_01.htm">Chapter 2: Bits and Pieces</a></td><td align="right" valign="top" width="172"><a href="ch02_08.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr></table></div><hr width="515" align="left"><!-- SECTION BODY --><h2 class="sect1">2.7. Context</h2><a name="INDEX-639"></a><a name="INDEX-640"></a><p>Until now we've seen several terms that can produce scalar values.Before we can discuss terms further, though, we must come to terms withthe notion of <em class="emphasis">context</em>.</p><h3 class="sect2">2.7.1. Scalar and List Context</h3><a name="INDEX-641"></a><a name="INDEX-642"></a><p><a name="INDEX-643"></a><a name="INDEX-644"></a>Every operation<a href="#FOOTNOTE-16">[16]</a> that you invoke ina Perl script is evaluated in a specific context, and how thatoperation behaves may depend on the requirements of that context.There are two major contexts: scalar and list. For example,assignment to a scalar variable, or to a scalar element of an arrayor hash, evaluates the righthand side in a <em class="emphasis">scalar context</em>:<blockquote><pre class="programlisting">$x = funkshun(); # scalar context$x[1] = funkshun(); # scalar context$x{"ray"} = funkshun(); # scalar context</pre></blockquote>But assignment to an array or a hash, or to a slice of either, evaluates therighthand side in a <em class="emphasis">list context</em>, even if the slice picks outonly one element:<blockquote><pre class="programlisting">@x = funkshun(); # list context@x[1] = funkshun(); # list context@x{"ray"} = funkshun(); # list context%x = funkshun(); # list context</pre></blockquote>Assignment to a list of scalars also provides a list context to therighthand side, even if there's only one element in the list:<blockquote><pre class="programlisting">($x,$y,$z) = funkshun(); # list context($x) = funkshun(); # list context</pre></blockquote>These rules do not change at all when you declare a variable by modifyingthe term with <tt class="literal">my</tt> or <tt class="literal">our</tt>, so we have:<blockquote><pre class="programlisting">my $x = funkshun(); # scalar contextmy @x = funkshun(); # list contextmy %x = funkshun(); # list contextmy ($x) = funkshun(); # list context</pre></blockquote><a name="INDEX-645"></a><a name="INDEX-646"></a></p><blockquote class="footnote"><a name="FOOTNOTE-16"></a><p>[16] Here we use the term "operation" looselyto mean either an operator or a term. The two concepts fuzz intoeach other when you start talking about functions that parse liketerms but look like unary operators.</p></blockquote><p><a name="INDEX-647"></a>You will be miserable until you learn the difference between scalarand list context, because certain operators (such as our mythical<tt class="literal">funkshun()</tt> function above) know which context they are in, andreturn a list in contexts wanting a list but a scalar value incontexts wanting a scalar. (If this is true of an operation, itwill be mentioned in the documentation for that operation.) Incomputer lingo, the operations are <em class="emphasis">overloaded</em> on their returntype. But it's a very simple kind of overloading, based only onthe distinction between singular and plural values, and nothingelse.</p><p><a name="INDEX-648"></a>If some operators respond to context, then obviously something aroundthem has to supply the context. We've shown that assignment cansupply a context to its right operand, but that's not terriblysurprising, since all operators supply some kind of context to each oftheir operands. What you really want to know is<em class="emphasis">which</em> operators supply <em class="emphasis">which</em>context to their operands. As it happens, you can easily tell whichones supply a list context because they all have<em class="replaceable">LIST</em> in their syntactic descriptions.Everything else supplies a scalar context. Generally, it's quiteintuitive.<a href="#FOOTNOTE-17">[17]</a> If necessary,you can force a scalar context onto an argument in the middle of a<em class="replaceable">LIST</em> by using the <tt class="literal">scalar</tt>pseudofunction. Perl provides no way to force a list context in ascalar context, because anywhere you would want a list context it'salready provided by the <em class="replaceable">LIST</em> of somecontrolling function.</p><blockquote class="footnote"><a name="FOOTNOTE-17"></a><p>[17] Note, however, that the list context of a<em class="replaceable">LIST</em> can propagate down through subroutinecalls, so it's not always obvious from inspection whether a givenstatement is going to be evaluated in a scalar or list context. Theprogram can find out its context within a subroutine by using the<tt class="literal">wantarray</tt> function.</p></blockquote><p><a name="INDEX-649"></a><a name="INDEX-650"></a><a name="INDEX-651"></a>Scalar context can be further classified into string context, numericcontext, and don't-care context. Unlike the scalar versus listdistinction we just made, operations never know or care which scalarcontext they're in. They simply return whatever kind of scalar valuethey want to and let Perl translate numbers to strings in stringcontext, and strings to numbers in numeric context. Some scalarcontexts don't care whether a string or a number or a reference isreturned, so no conversion will happen. This happens, for example,when you are assigning the value to another variable. The new variablejust takes on the same subtype as the old value.</p><h3 class="sect2">2.7.2. Boolean Context</h3><a name="INDEX-652"></a><a name="INDEX-653"></a><p>Another special don't-care scalar context is called <em class="emphasis">Boolean context</em>.Boolean context is simply any place where an expression isbeing evaluated to see whether it's true or false. When we say "true"and "false" in this book, we mean the technical definition that Perluses: a scalar value is true if it is not the null string <tt class="literal">""</tt> or thenumber 0 (or its string equivalent, <tt class="literal">"0"</tt>). A reference is alwaystrue because it represents an address which is never 0. An undefinedvalue (often called <tt class="literal">undef</tt>) is always false because it looks likeeither <tt class="literal">""</tt> or 0, depending on whether you treat it as a string or anumber. (List values have no Boolean value because list values arenever produced in a scalar context!)</p><p><a name="INDEX-654"></a><a name="INDEX-655"></a><a name="INDEX-656"></a>Because Boolean context is a don't-care context, it never causesany scalar conversions to happen, though of course the scalar contextitself is imposed on any operand that cares. And for manyoperands that care, the scalar they produce in scalar contextrepresents a reasonable Boolean value. That is, many operatorsthat would produce a list in list context can be used for a true/falsetest in Boolean context. For instance, in list context such asthat provided by the <tt class="literal">unlink</tt> operator, an array name produces thelist of its values:<blockquote><pre class="programlisting">unlink @files; # Delete all files, ignoring errors.</pre></blockquote><a name="INDEX-657"></a>But if you use the array in a conditional (that is, in a Booleancontext), the array knows it's in a scalar context and returns thenumber of elements in the array, which conveniently is true as longas there are any elements left. So supposing you wanted to getwarnings on each file that wasn't deleted properly, you might writea loop like this:<blockquote><pre class="programlisting">while (@files) { my $file = shift @files; unlink $file or warn "Can't delete $file: $!\n";}</pre></blockquote>Here <tt class="literal">@files</tt> is evaluated in the Boolean context supplied by the<tt class="literal">while</tt> statement, so Perl evaluates the array itself to see whetherit's a "true array" or a "false array". It's a true array as longas there are filenames in it, but it becomes a false array as soon asthe last filename is shifted out. Note that what we earlier saidstill holds. Despite the fact that an array contains (and canproduce) a list value, we are not evaluating a list value in scalarcontext. We are telling the array it's a scalar and asking whatit thinks of itself.</p><p>Do not be tempted to use <tt class="literal">defined @files</tt> for this. It doesn'twork because the <tt class="literal">defined</tt> function is asking whether a scalaris equal to <tt class="literal">undef</tt>, but an array is not a scalar. The simpleBoolean test suffices.</p><h3 class="sect2">2.7.3. Void Context</h3><a name="INDEX-658"></a><a name="INDEX-659"></a><a name="INDEX-660"></a><p>Another peculiar kind of scalar context is the <em class="emphasis">void context</em>. Thiscontext not only doesn't care what the return value's type is, itdoesn't even <em class="emphasis">want</em> a return value. From the standpoint of howfunctions work, it's no different from an ordinary scalar context.But if you have warnings enabled, the Perl compiler will warn you ifyou use an expression with no side effects in a place that doesn'twant a value, such as in a statement that doesn't return a value. Forexample, if you use a string as a statement:<blockquote><pre class="programlisting">"Camel Lot";</pre></blockquote>you may get a warning like this:<blockquote><pre class="programlisting">Useless use of a constant in void context in myprog line 123;</pre></blockquote></p><h3 class="sect2">2.7.4. Interpolative Context</h3><a name="INDEX-661"></a><a name="INDEX-662"></a><a name="INDEX-663"></a><a name="INDEX-664"></a><a name="INDEX-665"></a><a name="INDEX-666"></a><a name="INDEX-667"></a><a name="INDEX-668"></a><a name="INDEX-669"></a><a name="INDEX-670"></a><p>We mentioned earlier that double-quoted literal strings do backslashinterpretation and variable interpolation, but that the interpolativecontext (often called "double-quote context" because nobody canpronounce "interpolative") applies to more than just double-quotedstrings. Some other double-quotish constructs are the generalizedbacktick operator <tt class="literal">qx//</tt>, the pattern match operator <tt class="literal">m//</tt>, thesubstitution operator <tt class="literal">s///</tt>, and the quote regex operator, <tt class="literal">qr//</tt>.The substitution operator does interpolation on its left side beforedoing a pattern match, and then does interpolation on its right sideeach time the left side matches.</p><p>The interpolative context only happens inside quotes, or things thatwork like quotes, so perhaps it's not fair to call it a context in thesame sense as scalar and list contexts. (Then again, maybe it is.)</p><a name="INDEX-671"></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="ch02_06.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="ch02_08.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">2.6. Scalar Values</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">2.8. List Values and Arrays</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 + -