📄 ch04_08.htm
字号:
<html><head><title>Scoped Declarations (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="Scoped Declarations"><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="ch04_07.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="ch04_01.htm">Chapter 4: Statements and Declarations</a></td><td align="right" valign="top" width="172"><a href="ch04_09.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">4.8. Scoped Declarations</h2><a name="INDEX-1186"></a><a name="INDEX-1187"></a><a name="INDEX-1188"></a><p>Like global declarations, lexically scoped declarations have aneffect at the time of compilation. Unlike global declarations,lexically scoped declarations only apply from the point of thedeclaration through the end of the innermost enclosing scope (block,file, or <tt class="literal">eval</tt>--whichever comes first). That's why we call themlexically scoped, though perhaps "textually scoped" would be moreaccurate, since lexical scoping has little to do with lexicons.But computer scientists the world over know what "lexically scoped"means, so we perpetuate the usage here.</p><p><a name="INDEX-1189"></a>Perl alsosupports dynamically scoped declarations. A <em class="emphasis">dynamicscope</em> also extends to the end of the innermost enclosingblock, but in this case "enclosing" is defined dynamically at run timerather than textually at compile time. To put it another way, blocksnest dynamically by invoking other blocks, not by including them.This nesting of dynamic scopes may correlate somewhat to the nestingof lexical scopes, but the two are generally not identical, especiallywhen any subroutines have been invoked.</p><p><a name="INDEX-1190"></a>We mentioned that some aspects of <tt class="literal">use</tt> could beconsidered global declarations, but other aspects of<tt class="literal">use</tt> are lexically scoped. In particular,<tt class="literal">use</tt> not only imports package symbols but alsoimplements various magical compiler hints, known as<em class="emphasis">pragmas</em> (or if you're into classical forms,<em class="emphasis">pragmata</em>). Most pragmas are lexically scoped,including the <tt class="literal">use strict 'vars'</tt> pragma which forcesyou to declare your variables before you can use them. See the latersection <a href="ch04_09.htm#ch04-sect-pragma">Section 4.9, "Pragmas"</a>.</p><p><a name="INDEX-1191"></a><a name="INDEX-1192"></a><a name="INDEX-1193"></a>A <tt class="literal">package</tt> declaration, oddly enough, is itselflexically scoped, despite the fact that a package is a global entity.But a <tt class="literal">package</tt> declaration merely declares theidentity of the default package for the rest of the enclosing block.Undeclared, unqualified variable names<a href="#FOOTNOTE-5">[5]</a> are looked up in that package. In a sense,a package is never declared at all, but springs into existence whenyou refer to something that belongs to that package. It's all veryPerlish.</p><blockquote class="footnote"><a name="FOOTNOTE-5"></a><p>[5]Also unqualifiednames of subroutines, filehandles, directory handles, andformats.</p></blockquote><h3 class="sect2">4.8.1. Scoped Variable Declarations</h3><a name="INDEX-1194"></a><a name="INDEX-1195"></a><a name="INDEX-1196"></a><a name="INDEX-1197"></a><a name="INDEX-1198"></a><a name="INDEX-1199"></a><a name="INDEX-1200"></a><a name="INDEX-1201"></a><p>Most of the rest of the chapter is about using global variables.Or rather, it's about <em class="emphasis">not</em> using global variables. There are variousdeclarations that help you not use global variables--or at least, not usethem foolishly.</p><p>We already mentioned the <tt class="literal">package</tt> declaration, which wasintroduced into Perl long ago to allow globals to be split up intoseparate packages. This works pretty well for certain kinds ofvariables. Packages are used by libraries, modules, and classes tostore their interface data (and some of their semi-private data) to avoidconflicting with variables and functions of the same name in your mainprogram or in other modules. If you see someone write<tt class="literal">$Some::stuff</tt>,<a href="#FOOTNOTE-6">[6]</a>they're using the <tt class="literal">$stuff</tt> scalar variable from the package <tt class="literal">Some</tt>.See <a href="ch10_01.htm">Chapter 10, "Packages"</a>.</p><blockquote class="footnote"><a name="FOOTNOTE-6"></a><p>[6] Or the archaic <tt class="literal">$Some'stuff</tt>, whichprobably shouldn't be encouraged outside of Perl poetry.</p></blockquote><p><a name="INDEX-1202"></a><a name="INDEX-1203"></a><a name="INDEX-1204"></a><a name="INDEX-1205"></a><a name="INDEX-1206"></a><a name="INDEX-1207"></a>If this were all there were to the matter, Perl programs would quicklybecome unwieldy as they got longer. Fortunately, Perl's threescoping declarations make it easy to create completely privatevariables (using <tt class="literal">my</tt>), to give selective access to global ones (using<tt class="literal">our</tt>), and to provide temporary values to global variables (using<tt class="literal">local</tt>):<blockquote><pre class="programlisting">my $nose;our $House;local $TV_channel;</pre></blockquote>If more than one variable is listed, the list must be placed inparentheses. For <tt class="literal">my</tt> and <tt class="literal">our</tt>, the elements may only be simplescalar, array, or hash variables. For <tt class="literal">local</tt>, the constraints aresomewhat more relaxed: you may also localize entire typeglobs andindividual elements or slices of arrays and hashes:<blockquote><pre class="programlisting">my ($nose, @eyes, %teeth);our ($House, @Autos, %Kids);local (*Spouse, $phone{HOME});</pre></blockquote>Each of these modifiers offers a different sort of "confinement" to thevariables they modify. To oversimplify slightly: <tt class="literal">our</tt> confines namesto a scope, <tt class="literal">local</tt> confines values to a scope, and <tt class="literal">my</tt> confinesboth names and values to a scope.<a name="INDEX-1208"></a><a name="INDEX-1209"></a></p><p>Each of these constructs may be assigned to, though they differ inwhat they actually do with the values, since they have differentmechanisms for storing values. They also differ somewhat if you<em class="emphasis">don't</em> (as we didn't above) assign any values tothem: <tt class="literal">my</tt> and <tt class="literal">local</tt> cause thevariables in question to start out with values of<tt class="literal">undef</tt> or <tt class="literal">()</tt>, as appropriate;<tt class="literal">our</tt>, on the other hand, leaves the current value ofits associated global unchanged.</p><p><a name="INDEX-1210"></a><a name="INDEX-1211"></a><a name="INDEX-1212"></a>Syntactically, <tt class="literal">my</tt>, <tt class="literal">our</tt>, and <tt class="literal">local</tt> are simply modifiers(like adjectives) on an lvalue expression. When you assign to amodified lvalue, the modifier doesn't change whether the lvalue isviewed as a scalar or a list. To figure how the assignment willwork, just pretend that the modifier isn't there. So either of:<blockquote><pre class="programlisting">my ($foo) = <STDIN>;my @array = <STDIN>;</pre></blockquote> supplies a list context to the righthand side, while:<blockquote><pre class="programlisting">my $foo = <STDIN>;</pre></blockquote>supplies a scalar context.</p><p><a name="INDEX-1213"></a>Modifiers bind more tightly (with higher precedence) than the commadoes. The following example erroneously declares only one variable, nottwo, because the list following the modifier is not enclosed in parentheses.<blockquote><pre class="programlisting">my $foo, $bar = 1; # WRONG</pre></blockquote>This has the same effect as:<blockquote><pre class="programlisting">my $foo;$bar = 1;</pre></blockquote>You'll get a warning about the mistake if warnings are enabled,whether via the <tt class="userinput"><b>-w</b></tt> or <tt class="userinput"><b>-W</b></tt> command-line switches, or,preferably, through the <tt class="literal">use warnings</tt> declaration explainedlater in <a href="ch04_09.htm#ch04-sect-pragma">Section 4.9, "Pragmas"</a>.</p><p>In general, it's best to declare a variable in the smallestpossible scope that suits it. Since variables declared in acontrol-flow statement are visible only in the block governed bythat statement, their visibility is reduced. It reads better inEnglish this way, too.<blockquote><pre class="programlisting">sub check_warehouse { for my $widget (our @Current_Inventory) { print "I have a $widget in stock today.\n"; }}</pre></blockquote>The most frequently seen form of declaration is <tt class="literal">my</tt>, which declareslexically scoped variables for which both the names and valuesare stored in the current scope's temporary scratchpad and may notbe accessed globally. Closely related is the <tt class="literal">our</tt> declaration, whichenters a lexically scoped name in the current scope, just as <tt class="literal">my</tt> does,but actually refers to a global variable that anyone else could accessif they wished. In other words, it's a global variable masqueradingas a lexical.</p><p><a name="INDEX-1214"></a>The other form of scoping, dynamic scoping, applies to <tt class="literal">local</tt>variables, which despite the word "local" are really global variablesand have nothing to do with the local scratchpad.</p><h3 class="sect2">4.8.2. Lexically Scoped Variables: my</h3><p><a name="INDEX-1215"></a><a name="INDEX-1216"></a><a name="INDEX-1217"></a>To help you avoid the maintenance headaches of global variables, Perlprovides lexically scoped variables, often called<em class="emphasis">lexicals</em> for short. Unlike globals, lexicalsguarantee you privacy. Assuming you don't hand out references tothese private variables that would let them be fiddled withindirectly, you can be certain that every possible access to theseprivate variables is restricted to code within one discrete and easilyidentifiable section of your program. That's why we picked thekeyword <tt class="literal">my</tt>, after all.</p><p><a name="INDEX-1218"></a><a name="INDEX-1219"></a><a name="INDEX-1220"></a><a name="INDEX-1221"></a><a name="INDEX-1222"></a><a name="INDEX-1223"></a><a name="INDEX-1224"></a>A statement sequence may contain declarations of lexically scopedvariables. Such declarations tend to be placed at the front ofthe statement sequence, but this is not a requirement. In addition todeclaring variable names at compile time, the declarations act likeordinary run-time statements: each of them is elaborated within thesequence of statements as if it were an ordinary statement withoutthe modifier:<blockquote><pre class="programlisting">my $name = "fred";my @stuff = ("car", "house", "club");my ($vehicle, $home, $tool) = @stuff;</pre></blockquote>These lexical variables are totally hidden from the world outsidetheir immediately enclosing scope. Unlike the dynamic scopingeffects of <tt class="literal">local</tt> (see the next section), lexicals are hidden from any subroutinecalled from their scope. This is true even if the samesubroutine is called from itself or elsewhere--each instanceof the subroutine gets its own "scratchpad" of lexical variables.</p><p><a name="INDEX-1225"></a>Unlike block scopes, file scopes don't nest; there's no "enclosing"going on, at least not textually. If you load code from a separatefile with <tt class="literal">do</tt>, <tt class="literal">require</tt>, or <tt class="literal">use</tt>, the code in that file cannot access your lexicals, nor can you access lexicals from that file.</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -