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

📄 ch09_06.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
字号:
<html><head><title>More Elaborate Records (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 &amp; Associates, Inc."><meta name="DC.Source" content="" scheme="ISBN"><meta name="DC.Subject.Keyword" content=""><meta name="DC.Title" content="More Elaborate Records"><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="ch09_05.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="ch09_01.htm">Chapter 9: Data Structures</a></td><td align="right" valign="top" width="172"><a href="ch09_07.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">9.6. More Elaborate Records</h2><p><a name="INDEX-2161"></a><a name="INDEX-2162"></a><a name="INDEX-2163"></a>So far, what we've seen in this chapter are simple, two-level,homogeneous data structures: each element contains the same kind ofreferent as all the other elements at that level.  It certainlydoesn't have to be that way.  Any element can hold any kind of scalar,which means that it could be a string, a number, or a reference toanything at all.  The reference could be an array or hash reference,or a pseudohash, or a reference to a named or anonymous function, oran object.  The only thing you can't do is to stuff multiple referentsinto one scalar.  If you find yourself trying to do that, it's a signthat you need an array or hash reference to collapse multiple valuesinto one.</p><p>In the sections that follow, you will find code examples designed to illustrate many of thepossible types of data you might want to store in a record, which we'llimplement using a hash reference.  The keys are uppercase strings, aconvention sometimes employed (and occasionally unemployed, but only briefly)when the hash is being used as a specific record type.</p><h3 class="sect2">9.6.1. Composition, Access, and Printing ofMore Elaborate Records</h3><p><a name="INDEX-2164"></a><a name="INDEX-2165"></a><a name="INDEX-2166"></a>Here is a record with six disparate fields:<blockquote><pre class="programlisting">$rec = {    TEXT      =&gt; $string,    SEQUENCE  =&gt; [ @old_values ],    LOOKUP    =&gt; { %some_table },    THATCODE  =&gt; \&amp;some_function,    THISCODE  =&gt; sub { $_[0] ** $_[1] },    HANDLE    =&gt; \*STDOUT,};</pre></blockquote>The <tt class="literal">TEXT</tt> field is a simple string, so you can just print it:<blockquote><pre class="programlisting">print $rec-&gt;{TEXT};</pre></blockquote><tt class="literal">SEQUENCE</tt> and <tt class="literal">LOOKUP</tt> are regular array and hash references:<blockquote><pre class="programlisting">print $rec-&gt;{SEQUENCE}[0];$last = pop @{ $rec-&gt;{SEQUENCE} };print $rec-&gt;{LOOKUP}{"key"};($first_k, $first_v) = each %{ $rec-&gt;{LOOKUP} };</pre></blockquote><tt class="literal">THATCODE</tt> is a named subroutine and <tt class="literal">THISCODE</tt> is an anonymoussubroutine, but they're invoked identically:<blockquote><pre class="programlisting">$that_answer = $rec-&gt;{THATCODE}-&gt;($arg1, $arg2);$this_answer = $rec-&gt;{THISCODE}-&gt;($arg1, $arg2);</pre></blockquote>With an extra pair of braces, you can treat <tt class="literal">$rec-&gt;{HANDLE}</tt> asan indirect object:<blockquote><pre class="programlisting">print { $rec-&gt;{HANDLE} } "a string\n";</pre></blockquote>If you're using the <tt class="literal">FileHandle</tt> module, you can even treat thehandle as a regular object:<blockquote><pre class="programlisting">use FileHandle;$rec-&gt;{HANDLE}-&gt;autoflush(1);$rec-&gt;{HANDLE}-&gt;print("a string\n");</pre></blockquote></p><h3 class="sect2">9.6.2. Composition, Access, and Printing ofEven More Elaborate Records</h3><p>Naturally, the fields of your data structures can themselves bearbitrarily complex data structures in their own right:<blockquote><pre class="programlisting">%TV = (    flintstones =&gt; {        series   =&gt; "flintstones",        nights   =&gt; [ "monday", "thursday", "friday" ],        members  =&gt; [            { name =&gt; "fred",    role =&gt; "husband", age  =&gt; 36, },            { name =&gt; "wilma",   role =&gt; "wife",    age  =&gt; 31, },            { name =&gt; "pebbles", role =&gt; "kid",     age  =&gt;  4, },        ],    },    jetsons     =&gt; {        series   =&gt; "jetsons",        nights   =&gt; [ "wednesday", "saturday" ],        members  =&gt; [            { name =&gt; "george",  role =&gt; "husband", age  =&gt; 41, },            { name =&gt; "jane",    role =&gt; "wife",    age  =&gt; 39, },            { name =&gt; "elroy",   role =&gt; "kid",     age  =&gt;  9, },        ],    },    simpsons    =&gt; {        series   =&gt; "simpsons",        nights   =&gt; [ "monday" ],        members  =&gt; [            { name =&gt; "homer", role =&gt; "husband", age =&gt; 34, },            { name =&gt; "marge", role =&gt; "wife",    age =&gt; 37, },            { name =&gt; "bart",  role =&gt; "kid",     age =&gt; 11, },        ],    },);</pre></blockquote></p><h3 class="sect2">9.6.3. Generation of a Hash of Complex Records</h3><a name="INDEX-2167"></a><a name="INDEX-2168"></a><p><a name="INDEX-2169"></a>Because Perl is quite good at parsing complex data structures, youmight just put your data declarations in a separate file as regularPerl code, and then load them in with the <tt class="literal">do</tt> or<tt class="literal">require</tt> built-in functions.  Another popularapproach is to use a CPAN module (such as<tt class="literal">XML::Parser</tt>) to load in arbitrary data structuresexpressed in some other language (such as XML).</p><p>You can build data structures piecemeal:<blockquote><pre class="programlisting">$rec = {};$rec-&gt;{series} = "flintstones";$rec-&gt;{nights} = [ find_days() ];</pre></blockquote>Or read them in from a file (here, assumed to be in <tt class="literal">field=value</tt> syntax):<blockquote><pre class="programlisting">@members = ();while (&lt;&gt;) {     %fields = split /[\s=]+/;     push @members, { %fields };}$rec-&gt;{members} = [ @members ];</pre></blockquote>And fold them into larger data structures keyed by one of the subfields:<blockquote><pre class="programlisting">$TV{ $rec-&gt;{series} } = $rec;</pre></blockquote>You can use extra pointer fields to avoid duplicate data.  Forexample, you might want a <tt class="literal">"kids"</tt> field included in a person'srecord, which might be a reference to an array containing referencesto the kids' own records.  By having parts of your data structure referto other parts, you avoid the data skew that would result fromupdating the data in one place but not in another:<blockquote><pre class="programlisting">for $family (keys %TV) {    my $rec = $TV{$family};   # temporary pointer    @kids = ();    for $person ( @{$rec-&gt;{members}} ) {        if ($person-&gt;{role} =~ /kid|son|daughter/) {            push @kids, $person;        }    }    # $rec and $TV{$family} point to same data!    $rec-&gt;{kids} = [ @kids ];}</pre></blockquote>The <tt class="literal">$rec-&gt;{kids} = [ @kids ]</tt> assignment copiesthe array contents--but they are merely references to uncopied data.This means that if you age Bart as follows:<blockquote><pre class="programlisting">$TV{simpsons}{kids}[0]{age}++;            # increments to 12</pre></blockquote>then you'll see the following result, because <tt class="literal">$TV{simpsons}{kids}[0]</tt>and <tt class="literal">$TV{simpsons}{members}[2]</tt> both point to the same underlyinganonymous hash table:<blockquote><pre class="programlisting">print $TV{simpsons}{members}[2]{age};     # also prints 12</pre></blockquote>Now, to print the entire <tt class="literal">%TV</tt> structure:<blockquote><pre class="programlisting">for $family ( keys %TV ) {    print "the $family";    print " is on ", join (" and ", @{ $TV{$family}{nights} }), "\n";    print "its members are:\n";    for $who ( @{ $TV{$family}{members} } ) {        print " $who-&gt;{name} ($who-&gt;{role}), age $who-&gt;{age}\n";    }    print "children: ";    print join (", ", map { $_-&gt;{name} } @{ $TV{$family}{kids} } );    print "\n\n";}</pre></blockquote></p><a name="INDEX-2170"></a><a name="INDEX-2171"></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="ch09_05.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="ch09_07.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">9.5. Hashes of Functions</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">9.7. Saving Data Structures</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 &copy; 2001</a> O'Reilly &amp; 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 + -