📄 ch05_13.htm
字号:
<HTML><HEAD><TITLE>Recipe 5.12. Hashing References (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:32:53Z"><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="ch05_01.htm"TITLE="5. Hashes"><LINKREL="prev"HREF="ch05_12.htm"TITLE="5.11. Finding Common or Different Keys in Two Hashes"><LINKREL="next"HREF="ch05_14.htm"TITLE="5.13. Presizing a Hash"></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="ch05_12.htm"TITLE="5.11. Finding Common or Different Keys in Two Hashes"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 5.11. Finding Common or Different Keys in Two Hashes"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch05_01.htm"TITLE="5. Hashes"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch05_14.htm"TITLE="5.13. Presizing a Hash"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 5.13. Presizing a Hash"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch05-23263">5.12. Hashing References</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch05-pgfId-1154">Problem</A></H3><PCLASS="para">When you use <CODECLASS="literal">keys</CODE> on a hash whose keys are references, the references that <CODECLASS="literal">keys</CODE> returns no longer work. This situation often arises when you want to cross-reference two different hashes.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch05-pgfId-1160">Solution</A></H3><PCLASS="para">Use <ACLASS="indexterm"NAME="ch05-idx-1000006504-0"></A><ACLASS="indexterm"NAME="ch05-idx-1000006504-1"></A><ACLASS="indexterm"NAME="ch05-idx-1000006504-2"></A>Tie::RefHash:</P><PRECLASS="programlisting">use Tie::RefHash;tie %hash, "Tie::RefHash";# you may now use references as the keys to %hash</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch05-pgfId-1172">Discussion</A></H3><PCLASS="para">Hash keys are automatically "stringified," that is, treated as though they appeared between double quotes. In the case of numbers or strings, nothing is lost. This isn't the case with references, though.</P><PCLASS="para">Stringified references look like these:</P><PRECLASS="programlisting"><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>Class::Somewhere=HASH(0x72048)</I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>ARRAY(0x72048)</I></CODE></B></CODE></PRE><PCLASS="para">A stringified reference can't be dereferenced, because it is just a string and no longer a reference. This means you can't use references as the keys to a hash without losing their "magic."</P><PCLASS="para">Hand-rolled solutions to this problem involve maintaining a distinct hash whose keys are stringified references and whose values are the actual references. This is what Tie::RefHash does. We'll use IO objects for filehandles here to show you that even such strange references can be used to index a hash tied with Tie::RefHash.</P><PCLASS="para">Here's an example:</P><PRECLASS="programlisting">use Tie::RefHash;use IO::File;tie %name, "Tie::RefHash";foreach $filename ("/etc/termcap", "/vmunix", "/bin/cat") { $fh = IO::File->new("< $filename") or next; $name{$fh} = $filename;}print "open files: ", join(", ", values %name), "\n";foreach $file (keys %name) { seek($file, 0, 2); # seek to the end printf("%s is %d bytes long.\n", $name{$file}, tell($file));}</PRE><PCLASS="para">If you're storing objects as the keys to a hash, though, you almost always should be storing a unique attribute of the object (e.g., name or ID number) instead.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch05-pgfId-1218">See Also</A></H3><PCLASS="para">The documentation for the standard Tie::RefHash module; the <ACLASS="olink"HREF="../prog/ch04_05.htm#PERL2-CH-4-SECT-5.1">"Hard References Don't Work as Hash Keys"</A> section of <ACLASS="olink"HREF="../prog/ch04_01.htm">Chapter 4</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>, and the "Warning" section of <ICLASS="filename">perlref </I>(1) <ACLASS="indexterm"NAME="ch05-idx-1000006506-0"></A><ACLASS="indexterm"NAME="ch05-idx-1000006506-1"></A><ACLASS="indexterm"NAME="ch05-idx-1000006506-2"></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="ch05_12.htm"TITLE="5.11. Finding Common or Different Keys in Two Hashes"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 5.11. Finding Common or Different Keys in Two Hashes"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="ch05_14.htm"TITLE="5.13. Presizing a Hash"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 5.13. Presizing a Hash"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">5.11. Finding Common or Different Keys in Two Hashes</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">5.13. Presizing a Hash</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 © 2002</a> O'Reilly & 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 + -