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

📄 ch12_06.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 12.5. Determining the Caller's Package (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:41:33Z"><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="ch12_01.htm"TITLE="12. Packages, Libraries, and Modules"><LINKREL="prev"HREF="ch12_05.htm"TITLE="12.4. Making Variables Private to a Module"><LINKREL="next"HREF="ch12_07.htm"TITLE="12.6. Automating Module Clean-Up"></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="ch12_05.htm"TITLE="12.4. Making Variables Private to a Module"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 12.4. Making Variables Private to a Module"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch12_01.htm"TITLE="12. Packages, Libraries, and Modules"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch12_07.htm"TITLE="12.6. Automating Module Clean-Up"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 12.6. Automating Module Clean-Up"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch12-chap12_determining_0">12.5. Determining the Caller's Package</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch12-pgfId-716">Problem<ACLASS="indexterm"NAME="ch12-idx-1000005210-0"></A><ACLASS="indexterm"NAME="ch12-idx-1000005210-1"></A></A></H3><PCLASS="para">You need to find out the current or calling package.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch12-pgfId-722">Solution</A></H3><PCLASS="para">To find the current package:</P><PRECLASS="programlisting">$this_pack = __PACKAGE__;</PRE><PCLASS="para">To find the <ACLASS="indexterm"NAME="ch12-idx-1000005227-0"></A>caller's package:</P><PRECLASS="programlisting">$that_pack = caller();</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch12-pgfId-734">Discussion</A></H3><PCLASS="para">The <CODECLASS="literal">__PACKAGE__</CODE> symbol returns the package that the code is currently being compiled into. This doesn't interpolate into double-quoted strings:</P><PRECLASS="programlisting">print &quot;I am in package __PACKAGE__\n&quot;;              # WRONG!<BCLASS="emphasis.bold">I am in package __PACKAGE__</B></PRE><PCLASS="para">Needing to figure out the caller's package arose more often in older code that received as input a string of code to be <CODECLASS="literal">eval</CODE>uated, or a filehandle, format, or directory handle name. Consider a call to a hypothetical <CODECLASS="literal">runit</CODE> function:</P><PRECLASS="programlisting">package Alpha;runit('$line = &lt;TEMP&gt;');package Beta;sub runit {    my $codestr = shift;    eval $codestr;    die if $@;}</PRE><PCLASS="para">Because <CODECLASS="literal">runit</CODE> was compiled in a different package than was currently executing, when the <CODECLASS="literal">eval</CODE> runs, it will act as though it were passed <CODECLASS="literal">$Beta::line</CODE> and <CODECLASS="literal">Beta::TEMP</CODE>. The old workaround was to include your caller's package first:</P><PRECLASS="programlisting">package Beta;sub runit {    my $codestr = shift;    my $hispack = caller;    eval &quot;package $hispack; $codestr&quot;;    die if $@;}</PRE><PCLASS="para">That approach only works when <CODECLASS="literal">$line</CODE> is a global variable. If it's lexical, that won't help at all. Instead, arrange for <CODECLASS="literal">runit</CODE> to accept a reference to a subroutine:</P><PRECLASS="programlisting">package Alpha;runit( sub { $line = &lt;TEMP&gt; } );package Beta;sub runit {    my $coderef = shift;    &amp;$coderef();}</PRE><PCLASS="para">This not only works with lexicals, it has the added benefit of checking the code's syntax at compile time, which is a major win.</P><PCLASS="para">If all that's being passed in is a filehandle, it's more portable to use the <CODECLASS="literal">Symbol::qualify</CODE><ACLASS="indexterm"NAME="ch12-idx-1000005220-0"></A> function. This function takes a name and package to qualify the name into. If the name needs qualification, it fixes it; otherwise, it's left alone. But that's considerably less efficient than a <CODECLASS="literal">*</CODE> prototype.</P><PCLASS="para">Here's an example that reads and returns <EMCLASS="emphasis">n</EM> lines from a filehandle. The function qualifies the handle before working with it.</P><PRECLASS="programlisting">open (FH, &quot;&lt; /etc/termcap&quot;)    or die &quot;can't open /etc/termcap: $!&quot;;($a, $b, $c) = nreadline(3, 'FH');use Symbol ();use Carp;sub nreadline {    my ($count, $handle) = @_;    my(@retlist,$line);    croak &quot;count must be &gt; 0&quot; unless $count &gt; 0;    $handle = Symbol::qualify($handle, (<CODECLASS="literal">caller()</CODE>)[0]);    croak &quot;need open filehandle&quot; unless defined fileno($handle);    push(@retlist, $line) while defined($line = &lt;$handle&gt;) &amp;&amp; $count--;    return @retlist;}</PRE><PCLASS="para">If everyone who called your <CODECLASS="literal">nreadline</CODE> function <ACLASS="indexterm"NAME="ch12-idx-1000006218-0"></A>passed in the filehandle as a typeglob <CODECLASS="literal">*FH</CODE>, as a glob reference <CODECLASS="literal">\*FH</CODE>, or using FileHandle or IO::Handle objects, you wouldn't need to do this. It's only the possibility of a bare <CODECLASS="literal">&quot;FH&quot;</CODE> that requires qualification.<ACLASS="indexterm"NAME="ch12-idx-1000005212-0"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch12-pgfId-1000005916">See Also</A></H3><PCLASS="para">The documentation for the standard Symbol module, also found in <ACLASS="olink"HREF="../prog/ch07_01.htm">Chapter 7</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; the descriptions of the special symbols <CODECLASS="literal">__FILE__ </CODE>, <CODECLASS="literal">__LINE__</CODE> , and <CODECLASS="literal">__PACKAGE__</CODE> in <ICLASS="filename">perldata</I> (1); <ACLASS="xref"HREF="ch12_13.htm"TITLE="Reporting Errors and Warnings Like Built-Ins">Recipe 12.12</A></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="ch12_05.htm"TITLE="12.4. Making Variables Private to a Module"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 12.4. Making Variables Private to a Module"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="ch12_07.htm"TITLE="12.6. Automating Module Clean-Up"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 12.6. Automating Module Clean-Up"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">12.4. Making Variables Private to a Module</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">12.6. Automating Module Clean-Up</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 + -