📄 ch02_05.htm
字号:
<tt class="literal">$Cat::bert</tt>. See <a href="ch10_01.htm">Chapter 10, "Packages"</a>.</p><p><a name="INDEX-501"></a><a name="INDEX-502"></a><a name="INDEX-503"></a>Variables attached to a lexical scope are not in any package,so lexically scoped variable names may not contain the <tt class="literal">::</tt> sequence.(Lexically scoped variables are declared with a <tt class="literal">my</tt> declaration.)</p><h3 class="sect2">2.5.1. Name Lookups</h3><p><a name="INDEX-504"></a><a name="INDEX-505"></a>So the question is, what's in a name? How does Perl figure out whatyou mean if you just say <tt class="literal">$bert</tt>? Glad you asked. Here are the rulesthe Perl parser uses while trying to understand an unqualified name incontext:</p><ol><li><p><a name="INDEX-506"></a><a name="INDEX-507"></a><a name="INDEX-508"></a>First, Perl looks earlier in the immediately enclosing block to seewhether the variable is declared in that same block with a<tt class="literal">my</tt> (or <tt class="literal">our</tt>) declaration (seethose entries in <a href="ch29_01.htm">Chapter 29, "Functions"</a>, as well as thesection <a href="ch04_08.htm#ch04-sect-sd">Section 2.8, "Scoped Declarations"</a> in <a href="ch04_01.htm">Chapter 4, "Statements and Declarations"</a>). If there is a<tt class="literal">my</tt> declaration, the variable is lexically scopedand doesn't exist in any package--it exists only in that lexical scope(that is, in the block's scratchpad). Because lexical scopes areunnamed, nobody outside that chunk of program can even name yourvariable.<a href="#FOOTNOTE-8">[8]</a></p><blockquote class="footnote"><a name="FOOTNOTE-8"></a><p>[8]If you use an <tt class="literal">our</tt>declaration instead of a <tt class="literal">my</tt> declaration, this onlydeclares a lexically scoped <em class="emphasis">alias</em> (a nickname)for a package variable, rather than declaring a true lexically scopedvariable the way <tt class="literal">my</tt> does. Outside code can stillget at the real variable through its package, but in all otherrespects an <tt class="literal">our</tt> declaration behaves like a<tt class="literal">my</tt> declaration. This is handy when you're tryingto limit your own use of globals with the <tt class="literal">usestrict</tt> pragma (see the <tt class="literal">strict</tt> pragma in<a href="ch31_01.htm">Chapter 31, "Pragmatic Modules"</a>). But you should alwaysprefer <tt class="literal">my</tt> if you don't need aglobal.</p></blockquote></li><li><p>If that doesn't work, Perl looks for the block enclosing that blockand tries again for a lexically scoped variable in the larger block.Again, if Perl finds one, the variable belongs only to the lexicalscope from the point of declaration through the end of the block inwhich it is declared--including any nested blocks, like the one wejust came from in step 1. If Perl doesn't find a declaration, itrepeats step 2 until it runs out of enclosing blocks.</p></li><li><p><a name="INDEX-509"></a><a name="INDEX-510"></a><a name="INDEX-511"></a>When Perl runs out of enclosing blocks, it examines the wholecompilation unit for declarations as if it were a block. (A<em class="emphasis">compilation unit</em> is just the entire current file, or the stringcurrently being compiled by an <tt class="literal">eval</tt><em class="replaceable">STRING</em>operator.) If thecompilation unit is a file, that's the largest possible lexical scope,and Perl will look no further for lexically scoped variables, so we goto step 4. If the compilation unit is a string, however, things getfancier. A string compiled as Perl code at run time pretends that it'sa block within the lexical scope from which the <tt class="literal">eval</tt><em class="replaceable">STRING</em> isrunning, even though the actual boundaries of the lexical scope are thelimits of the string containing the code rather than any real braces.So if Perl doesn't find the variable in the lexical scope of thestring, we pretend that the <tt class="literal">eval</tt><em class="replaceable">STRING</em> is a block and go back tostep 2, only this time starting with the lexical scope of the <tt class="literal">eval</tt><em class="replaceable">STRING</em> operator instead of the lexical scope inside its string.</p></li><li><p><a name="INDEX-512"></a><a name="INDEX-513"></a>If we get here, it means Perl didn't find any declaration (either<tt class="literal">my</tt> or <tt class="literal">our</tt>) for your variable.Perl now gives up on lexically scoped variables and assumes that yourvariable is a package variable. If the <tt class="literal">strict</tt>pragma is in effect, you will now get an error, unless the variable isone of Perl's predefined variables or has been imported into thecurrent package. This is because that pragma disallows the use ofunqualified global names. However, we aren't done with lexical scopesjust yet. Perl does the same search of lexical scopes as it did insteps 1 through 3, only this time it searches for<tt class="literal">package</tt> declarations instead of variabledeclarations. If it finds such a package declaration, it knows thatthe current code is being compiled for the package in question andprepends the declared package name to the front of the variable.</p></li><li><p><a name="INDEX-514"></a><a name="INDEX-515"></a>If there is no package declaration in any surrounding lexical scope,Perl looks for the variable name in the unnamed top-level package,which happens to have the name <tt class="literal">main</tt> when it isn'tgoing around without a name tag. So in the absence of anydeclarations to the contrary, <tt class="literal">$bert</tt> means the sameas <tt class="literal">$::bert</tt>, which means the same as<tt class="literal">$main::bert</tt>. (But because <tt class="literal">main</tt>is just another package in the top-level unnamed package, it's also<tt class="literal">$::main::bert</tt>, and<tt class="literal">$main::main::bert</tt>,<tt class="literal">$::main::main::bert</tt> and so on. This could beconstrued as a useless fact. But see "Symbol Tables" in<a href="ch10_01.htm">Chapter 10, "Packages"</a>.)</p></li></ol><p><a name="INDEX-516"></a>There are several implications to these search rules that might notbe obvious, so we'll make them explicit.</p><ul><li><p><a name="INDEX-"></a>Because the file is the largest possible lexical scope, a lexicallyscoped variable can never be visible outside the file in which it's declared. File scopes do not nest.</p></li><li><p>Any particular bit of Perl is compiled in at least one lexical scopeand exactly one package scope. The mandatory lexical scope is, ofcourse, the file itself. Additional lexical scopes are provided byeach enclosing block. All Perl code is also compiled in the scope ofexactly one package, and although the declaration of which package you'rein is lexically scoped, packages themselves are not lexically constrained.That is, they're global.</p></li><li><p>An unqualified variable name may therefore be searched for in manylexical scopes, but only one package scope, whichever one is currently ineffect (which is lexically determined).</p></li><li><p>A variable name may only attach to one scope. Although at least twodifferent scopes (lexical and package) are active everywhere in yourprogram, a variable can only exist in one of those scopes.</p></li><li><p>An unqualified variable name can therefore resolve to only a singlestorage location, either in the first enclosing lexical scope inwhich it is declared, or else in the current package--but not both.The search stops as soon as that storage location is resolved, andany storage location that it would have found had the search continuedis effectively hidden.</p></li><li><p>The location of the typical variable name can be completely determinedat compile time.</p></li></ul><p></p><p><a name="INDEX-517"></a><a name="INDEX-518"></a>Now that you know all about how the Perl compiler deals with names, yousometimes have the problem that you don't <em class="emphasis">know</em> the name of what youwant at compile time. Sometimes you want to name something indirectly;we call this the problem of <em class="emphasis">indirection</em>. So Perl provides amechanism: you can always replace an alphanumeric variable name with ablock containing an expression that returns a <em class="emphasis">reference</em> to the realdata. For instance, instead of saying:<blockquote><pre class="programlisting">$bert</pre></blockquote>you might say:<blockquote><pre class="programlisting">${ some_expression() }</pre></blockquote>and if the <tt class="literal">some_expression()</tt> function returns areference to variable <tt class="literal">$bert</tt> (or even the string,<tt class="literal">"bert"</tt>), it will work just as if you'd said<tt class="literal">$bert</tt> in the first place. On the other hand,if the function returns a reference to <tt class="literal">$ernie</tt>,you'll get his variable instead. The syntax shown is the most general(and least legible) form of indirection, but we'll cover severalconvenient variations in <a href="ch08_01.htm">Chapter 8, "References"</a>.</p><a name="INDEX-519"></a><a name="INDEX-520"></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_04.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_06.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">2.4. Variables</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.6. Scalar Values</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 + -