📄 ch08_02.htm
字号:
<html><head><title>Attribute::Handlers (Perl in a Nutshell, 2nd Edition)</title><link rel="stylesheet" type="text/css" href="../style/style1.css" /><meta name="DC.Creator" content="Stephen Spainhour" /><meta name="DC.Format" content="text/xml" scheme="MIME" /><meta name="DC.Language" content="en-US" /><meta name="DC.Publisher" content="O'Reilly & Associates, Inc." /><meta name="DC.Source" scheme="ISBN" content="0596002416L" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="Perl in a Nutshell, 2nd Edition" /><meta name="DC.Type" content="Text.Monograph" /></head><body bgcolor="#ffffff"><img src="gifs/smbanner.gif" usemap="#banner-map" border="0" alt="Book Home" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Java and XSLT" /><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch08_01.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0" /></a></td><td align="center" valign="top" width="228" /><td align="right" valign="top" width="228"><a href="ch08_03.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0" /></a></td></tr></table></div><h2 class="sect1">8.2. Attribute::Handlers</h2><p><a name="INDEX-1269" />Implements a simpler definition ofattribute handlers. When inherited by a package, Attribute::Handlersallows that package's class to define handlersubroutines for specific attributes. When inherited by a package,these handlers will be called by the same names as the originalattribute-handling subroutines. Attribute handlers will be called atone of the following compilation phases: BEGIN, CHECK, INIT, or ENDblocks. Note that Attribute::Handlers is shipped with the Perl sourcekit as of Version 5.8.</p><p><a name="INDEX-1270" />Handlers aredefined as subroutines and named as the desired attribute. In thefollowing example, the attribute is <tt class="literal">:ATTR</tt>, whichlives in a subroutine that's called<tt class="literal">Nate1()</tt> in the HandlerBing class:</p><blockquote><pre class="code">package HandlerBing;use Attribute::Handlers;sub Nate1 :ATTR { my(@attrs) = @_; # We simply want to test by dumping the attributes print "attributes: \n", join("\n", @attrs), "\n";} # true.1;</pre></blockquote><p>This stub for the HandlerBing class creates a handler for theattribute <tt class="literal">:Nate1</tt>. When you want to use thishandler while within HandlerBing, you can do the following:</p><blockquote><pre class="code">sub Nate2 :Nate1 { my (@stuff) = @_; print STDERR "in Nate2 ", join("\n", @stuff), "\n";}</pre></blockquote><p>When you call <tt class="literal">Nate2</tt>, it invokes the<tt class="literal">Nate1</tt> handler and passes the following elementsinto the <tt class="literal">@_</tt> array:</p><dl><dt><b><tt class="literal">0</tt></b></dt><dd>The name of the package in which the handler was declared</p></dd><dt><b><tt class="literal">1</tt></b></dt><dd>A reference to the symbol table entry (a typeglob) that contains thesubroutine</p></dd><dt><b><tt class="literal">2</tt></b></dt><dd>A reference to the subroutine</p></dd><dt><b><tt class="literal">3</tt></b></dt><dd>The name of the attribute itself</p></dd><dt><b><tt class="literal">4</tt></b></dt><dd>Any data associated with that attribute</p></dd><dt><b><tt class="literal">5</tt></b></dt><dd>The name of the compilation phase in which the handler was invoked</p></dd></dl><p>The same holds true for declaring any variables with the<tt class="literal">:Nate1</tt> attribute within HandlerBing:</p><blockquote><pre class="code">my $monica :Nate1;my $phoebe :Nate1;</pre></blockquote><p>Attribute::Handlers also supports typed lexicals. This is a nicefeature, since you can invoke a handler from a package that definesanother one from whatever package you're in (orwriting!). For example:</p><blockquote><pre class="code">package MustNotSeeTV; my HandlerBring $whatever : Nate1; # true1;</pre></blockquote><p>You can apply handlers only by type, if you wish. You can do this bypassing a built-in type to <tt class="literal">:ATTR</tt>:</p><blockquote><pre class="code">package ReRun; sub Tiresome :ATTR(HASH) { print "your reruns have become tiresome\n"; } # true1;</pre></blockquote><p>In the above code, <tt class="literal">Tiresome</tt> is an attributehandler that applies only to <tt class="literal">HASH</tt> es. Andcertainly, you can declare separate handlers (of the same names) forthe other types.</p><p>If you have problems passing certain data to a handler, such as<tt class="literal">now..later</tt> or <tt class="literal">laugh@you</tt>, youcan use the <tt class="literal">RAWDATA</tt> type to pass this datacleanly:</p><blockquote><pre class="code">sub RawLikeSushi : ATTR(RAWDATA) { ... do something ... }</pre></blockquote><p><a name="INDEX-1271" />Attribute::Handlersimplements the following diagnostics (from the Attribute::Handlersmanpage):</p><dl><dt><i>Bad attribute type: <tt class="literal">ATTR(%s)</tt></i></dt><dd>An attribute handler was specified with an<tt class="literal">:ATTR(</tt><em class="replaceable"><tt>ref_type</tt></em><tt class="literal">)</tt>,but the type of referent it was defined to handlewasn't one of the five permitted:<tt class="literal">SCALAR</tt>, <tt class="literal">ARRAY</tt>,<tt class="literal">HASH</tt>, <tt class="literal">CODE</tt>, or<tt class="literal">ANY</tt>.</p></dd><dt><i>Attribute handler <tt class="literal">%s</tt> doesn't handle <tt class="literal">%s</tt> attributes</i></dt><dd>A handler for attributes of the specified name was defined, but notfor the specified type of declaration. Typically encountered whentrying to apply a <tt class="literal">VAR</tt> attribute handler to asubroutine, or a <tt class="literal">SCALAR</tt> attribute handler toanother type of variable.</p></dd><dt><i>Declaration of <tt class="literal">%s</tt> attribute in <tt class="literal">%s</tt> package may clash with future reserved word</i></dt><dd>A handler for an attribute with an all-lowercase name was declared.An attribute with an all-lowercase name might mean something to Perlitself someday, even though most don't yet. Use amixed-case attribute name instead.</p></dd><dt><i>Can't have two <tt class="literal">ATTR</tt> specifiers on one subroutine</i></dt><dd>You just can't, okay? Instead, put all thespecifications together, separated by commas in a single<tt class="literal">ATTR(</tt><em class="replaceable"><tt>specifications</tt></em><tt class="literal">)</tt>.</p></dd><dt><i>Can't autotie a <tt class="literal">%s</tt></i></dt><dd>You can declare autoties only for types <tt class="literal">SCALAR</tt>,<tt class="literal">ARRAY</tt>, and <tt class="literal">HASH</tt>.They're the only things (apart from typeglobs, whichare not declarable) that Perl can tie.</p></dd><dt><i>Internal error: <tt class="literal">%s</tt> symbol went missing</i></dt><dd>Something is rotten in the state of the program. An attributedsubroutine ceased to exist between the point where it was declaredand the point where its attribute handler(s) would have been called.</p></dd><dt><i>Won't be able to apply an <tt class="literal">END</tt> handler</i></dt><dd>You tried to define an <tt class="literal">END</tt> handler for anattribute that is applied to a lexical variable. Since the variablemay not be available during <tt class="literal">END</tt>, this willfail.<a name="INDEX-1272" /></p></dd></dl><hr width="684" align="left" /><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch08_01.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0" /></a></td><td align="right" valign="top" width="228"><a href="ch08_03.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0" /></a></td></tr><tr><td align="left" valign="top" width="228">8. Standard Modules</td><td align="center" valign="top" width="228"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0" /></a></td><td align="right" valign="top" width="228">8.3. attributes</td></tr></table></div><hr width="684" align="left" /><img src="../gifs/navbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links" /><p><p><font size="-1"><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 + -