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

📄 ch10_03.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 10.2. Making Variables Private to a Function (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen &amp; Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:39:36Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch10_01.htm"TITLE="10. Subroutines"><LINKREL="prev"HREF="ch10_02.htm"TITLE="10.1. Accessing Subroutine Arguments"><LINKREL="next"HREF="ch10_04.htm"TITLE="10.3. Creating Persistent Private Variables"></HEAD><BODYBGCOLOR="#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="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch10_02.htm"TITLE="10.1. Accessing Subroutine Arguments"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 10.1. Accessing Subroutine Arguments"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch10_01.htm"TITLE="10. Subroutines"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch10_04.htm"TITLE="10.3. Creating Persistent Private Variables"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 10.3. Creating Persistent Private Variables"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch10-30489">10.2. Making Variables Private to a Function</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch10-pgfId-178">Problem<ACLASS="indexterm"NAME="ch10-idx-1000004648-0"></A><ACLASS="indexterm"NAME="ch10-idx-1000004648-1"></A><ACLASS="indexterm"NAME="ch10-idx-1000004648-2"></A><ACLASS="indexterm"NAME="ch10-idx-1000004648-3"></A><ACLASS="indexterm"NAME="ch10-idx-1000004648-4"></A></A></H3><PCLASS="para">Your subroutine needs temporary variables. You shouldn't use global variables, because another subroutine might also use the same variables.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch10-pgfId-184">Solution</A></H3><PCLASS="para">Use <CODECLASS="literal">my</CODE> to declare a variable private to a region of your program:</P><PRECLASS="programlisting">sub somefunc {    my $variable;                 # $variable is invisible outside somefunc()    my ($another, @an_array, %a_hash);     # declaring many variables at once    # ...}</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch10-pgfId-202">Discussion</A></H3><PCLASS="para">The <CODECLASS="literal">my</CODE> operator confines a variable to a particular region of code in which it can be used and accessed. Outside that region, it can't be accessed. This region is called its <EMCLASS="emphasis">scope</EM>.</P><PCLASS="para">Variables declared with <CODECLASS="literal">my</CODE> have <EMCLASS="emphasis">lexical scope</EM><ACLASS="indexterm"NAME="ch10-idx-1000004658-0"></A>, which means that they exist only within a particular textual area of code. For instance, the scope of <CODECLASS="literal">$variable</CODE> in the Solution is the function it was defined in, <CODECLASS="literal">somefunc</CODE>. When a call to <CODECLASS="literal">somefunc</CODE> is made, the variable is created. The variable is destroyed when the function call ends. The variable can be accessed within the function, but not outside of it.</P><PCLASS="para">A lexical scope is usually a block of code with a set of braces around it, such as those defining the body of the <CODECLASS="literal">somefunc</CODE> subroutine or those marking the code blocks of <CODECLASS="literal">if</CODE>, <CODECLASS="literal">while</CODE>, <CODECLASS="literal">for</CODE>, <CODECLASS="literal">foreach</CODE>, and <CODECLASS="literal">eval</CODE> statements. Lexical scopes may also be an entire file or strings given to <CODECLASS="literal">eval</CODE>. Since a lexical scope is usually a block, we'll sometimes talk about lexical variables (variables with lexical scope) being only visible in their block when we mean that they're only visible in their scope. Forgive us. Otherwise, we'll be using the words "scope" and "sub" more than a WWII Navy movie.</P><PCLASS="para">Because the parts of code that can see a <CODECLASS="literal">my</CODE> variable are determined at compile time and don't change after that, lexical scoping is sometimes misleadingly referred to as static scoping. Lexical scoping is in contrast to <EMCLASS="emphasis">dynamic</EM> scoping, which we'll cover in <ACLASS="xref"HREF="ch10_14.htm"TITLE="Saving Global Values">Recipe 10.13</A>.</P><PCLASS="para">You can combine a <CODECLASS="literal">my</CODE> declaration with an assignment. Use parentheses when defining more than one variable:</P><PRECLASS="programlisting">my ($name, $age) = @ARGV;my $start        = fetch_time();</PRE><PCLASS="para">These lexical variables behave as you would expect a local variable to. Nested blocks can see lexicals declared in outer blocks, but not in unrelated blocks:</P><PRECLASS="programlisting">my ($a, $b) = @pair;my $c = fetch_time();sub check_x {    my $x = $_[0];           my $y = &quot;whatever&quot;;      run_check();    if ($condition) {        print &quot;got $x\n&quot;;    }}</PRE><PCLASS="para">In the preceding code, the <CODECLASS="literal">if</CODE> block inside the function can access the private <CODECLASS="literal">$x</CODE> variable. However, the <CODECLASS="literal">run_check</CODE> function called from within that scope cannot access <CODECLASS="literal">$x</CODE> or <CODECLASS="literal">$y</CODE> because <CODECLASS="literal">run_check</CODE> was presumably defined in another scope. However, <CODECLASS="literal">check_x</CODE> could access <CODECLASS="literal">$a</CODE>, <CODECLASS="literal">$b</CODE>, or <CODECLASS="literal">$c</CODE> from the outer scope because the function was defined in the same scope as those three variables.</P><PCLASS="para">Don't nest the declaration of named subroutines within the declarations of other named subroutines. Such subroutines, unlike proper closures, will not get the right bindings of the lexical variables. <ACLASS="xref"HREF="ch10_17.htm"TITLE="Nesting Subroutines">Recipe 10.16</A> shows how to cope with this restriction.</P><PCLASS="para">When a lexical goes out of scope, its storage is freed unless a reference to its value's storage space still exists, as with <CODECLASS="literal">@arguments</CODE> in the following code:</P><PRECLASS="programlisting">sub save_array {    my @arguments = @_;    push(@Global_Array, \@arguments);}</PRE><PCLASS="para">Perl's garbage collection system knows not to deallocate things until they're no longer used. This is why we can return a reference to a private variable without leaking memory.<ACLASS="indexterm"NAME="ch10-idx-1000004650-0"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch10-pgfId-236">See Also</A></H3><PCLASS="para">The section on <ACLASS="olink"HREF="../prog/ch02_06.htm#PERL2-CH-2-SECT-6.8">"Scoped Declarations"</A> in <ACLASS="olink"HREF="../prog/ch02_01.htm">Chapter 2</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A> and the section on "Private Variables via my(  )" in <ICLASS="filename">perlsub </I>(1)</P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch10_02.htm"TITLE="10.1. Accessing Subroutine Arguments"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 10.1. Accessing Subroutine Arguments"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch10_04.htm"TITLE="10.3. Creating Persistent Private Variables"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 10.3. Creating Persistent Private Variables"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">10.1. Accessing Subroutine Arguments</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">10.3. Creating Persistent Private Variables</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <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 + -