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

📄 ch13_05.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 13.4. Managing Class Data (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:42:18Z"><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="ch13_01.htm"TITLE="13. Classes, Objects, and Ties"><LINKREL="prev"HREF="ch13_04.htm"TITLE="13.3. Managing Instance Data"><LINKREL="next"HREF="ch13_06.htm"TITLE="13.5. Using Classes as Structs"></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="ch13_04.htm"TITLE="13.3. Managing Instance Data"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 13.3. Managing Instance Data"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch13_01.htm"TITLE="13. Classes, Objects, and Ties"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_06.htm"TITLE="13.5. Using Classes as Structs"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 13.5. Using Classes as Structs"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch13-chap13_managing_1">13.4. Managing Class Data</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-581">Problem<EMCLASS="emphasis"></EM><ACLASS="indexterm"NAME="ch13-idx-1000004515-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004515-1"></A><ACLASS="indexterm"NAME="ch13-idx-1000004515-2"></A></A></H3><PCLASS="para">You need a method to be called on behalf of the whole class, not just on one object. This might be a procedural request, or it might be a global data attribute shared by all instances of the class.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-587">Solution</A></H3><PCLASS="para">Instead of expecting a reference as their first argument as object methods do, <ACLASS="indexterm"NAME="ch13-idx-1000004519-0"></A>class methods expect a string containing name of the class. Class methods access package data, not object data, as in the <CODECLASS="literal">population</CODE> method shown here:</P><PRECLASS="programlisting">package Person;$Body_Count = 0; sub population { return $Body_Count }sub new {                                   # constructor    $Body_Count++;    return bless({}, shift);}sub DESTROY { --$BodyCount }                # destructor# later, the user can say this:package main;for (1..10) { push @people, Person-&gt;new }printf &quot;There are %d people alive.\n&quot;, Person-&gt;population();<BCLASS="emphasis.bold">There are 10 people alive.</B></PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-633">Discussion</A></H3><PCLASS="para">Normally, each object has its own complete state stored within itself. The value of a data attribute in one object is unrelated to the value that attribute might have in another instance of the same class. For example, setting <EMCLASS="emphasis">her</EM> gender here does nothing to <EMCLASS="emphasis">his</EM> gender, because they are different objects with distinct states:</P><PRECLASS="programlisting">$him = Person-&gt;<CODECLASS="literal">new()</CODE>;$him-&gt;gender(&quot;male&quot;);$her = Person-&gt;<CODECLASS="literal">new()</CODE>;$her-&gt;gender(&quot;female&quot;);</PRE><PCLASS="para">Imagine a classwide attribute where changing the attribute for one instance changes it for all of them. Just as some programmers prefer capitalized global variables, some prefer uppercase names when the method affects class data instead of instance data. Here's an example of using a class method called <CODECLASS="literal">Max_Bounds</CODE>:</P><PRECLASS="programlisting">FixedArray-&gt;Max_Bounds(100);                # set for whole class$alpha = FixedArray-&gt;new();printf &quot;Bound on alpha is %d\n&quot;, $alpha-&gt;Max_Bounds();<CODECLASS="userinput"><B><CODECLASS="replaceable"><I>100</I></CODE></B></CODE>$beta = FixedArray-&gt;new();$beta-&gt;Max_Bounds(50);                      # still sets for whole classprintf &quot;Bound on alpha is %d\n&quot;, $alpha-&gt;Max_Bounds();<CODECLASS="userinput"><B><CODECLASS="replaceable"><I>50</I></CODE></B></CODE></PRE><PCLASS="para">The implementation is simple:</P><PRECLASS="programlisting">package FixedArray;$Bounds = 7;  # defaultsub new { bless( {}, shift ) }sub Max_Bounds {    my $proto  = shift;    $Bounds    = shift if @_;          # allow updates    return $Bounds;} </PRE><PCLASS="para">To make the value effectively read only, simply remove the update possibility, as in:</P><PRECLASS="programlisting">sub Max_Bounds { $Bounds }</PRE><PCLASS="para">If you're deeply paranoid, make <CODECLASS="literal">$Bounds</CODE> a lexical variable private to the scope of the file containing the class. Then no one could say <CODECLASS="literal">$FixedArray::Bounds</CODE> to discover its values. They'd be forced to go through the method interface instead.</P><PCLASS="para">Here's a tip to help build scalable classes: store object data on the object's namespace (in the hash), and store class data in the class namespace (package variables or file-scoped lexicals). Only class methods should directly access classwide attributes. Object methods should only access instance data. If the object method needs access to class data, its constructor should store a reference to that data in the object. Here's an example:</P><PRECLASS="programlisting">sub new {    my $class = shift;    my $self = bless({}, $class);    $self-&gt;{Max_Bounds_ref} = \$Bounds;    return $self;} <EMCLASS="emphasis"></EM><ACLASS="indexterm"NAME="ch13-idx-1000004521-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004521-1"></A><ACLASS="indexterm"NAME="ch13-idx-1000004521-2"></A></PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-705">See Also</A></H3><PCLASS="para"><ICLASS="filename">perltoot </I>(1), <ICLASS="filename">perlobj </I>(1), and <ICLASS="filename">perlbot </I>(1); the section on <ACLASS="olink"HREF="../prog/ch05_05.htm#PERL2-CH-5-SECT-5.9">"Class Context and the Object"</A> in <ACLASS="olink"HREF="../prog/ch05_01.htm">Chapter 5</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; <ACLASS="xref"HREF="ch13_04.htm"TITLE="Managing Instance Data">Recipe 13.3</A>; the <CODECLASS="literal">places</CODE> method in the <ACLASS="xref"HREF="ch13_15.htm#ch13-16506"TITLE="Example: Overloaded FixNum Class">"Example: Overloaded FixNum Class</A>" example in <ACLASS="xref"HREF="ch13_15.htm"TITLE="Overloading Operators">Recipe 13.14</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="ch13_04.htm"TITLE="13.3. Managing Instance Data"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 13.3. Managing Instance Data"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="ch13_06.htm"TITLE="13.5. Using Classes as Structs"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 13.5. Using Classes as Structs"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">13.3. Managing Instance Data</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">13.5. Using Classes as Structs</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 + -