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

📄 ch14_01.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<html><head><title>Tied Variables (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="Tied Variables"><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="ch13_10.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="part2.htm">Part 2: The Gory Details</a></td><td align="right" valign="top" width="172"><a href="ch14_02.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr></table></div><hr width="515" align="left"><!-- SECTION BODY --><h1 class="chapter">Chapter 14.  Tied Variables</h1><div class="htmltoc"><h4 class="tochead">Contents:</h4><p><a href="ch14_01.htm">Tying Scalars</a><br><a href="ch14_02.htm">Tying Arrays</a><br><a href="ch14_03.htm">Tying Hashes</a><br><a href="ch14_04.htm">Tying Filehandles</a><br><a href="ch14_05.htm">A Subtle Untying Trap</a><br><a href="ch14_06.htm">Tie Modules on CPAN</a><br></p></div><a name="INDEX-2654"></a><a name="INDEX-2655"></a><a name="INDEX-2656"></a><a name="INDEX-2657"></a><a name="INDEX-2658"></a><p>Some human endeavors require a disguise.  Sometimes the intent is todeceive, but more often, the intent is to communicate something trueat a deeper level.  For instance, many job interviewers expect you todress up in a tie to indicate that you're seriously interested infitting in, even though both of you know you'll never wear a tie onthe job.  It's odd when you think about it: tying a piece of clotharound your neck can magically get you a job.  In Perl culture, the<em class="emphasis">tie</em> operator plays a similar role: it lets youcreate a seemingly normal variable that, behind the disguise, isactually a full-fledged Perl object that is expected to have aninteresting personality of its own.  It's just an odd bit of magic,like pulling Bugs Bunny out of a hat.</p><p><a name="INDEX-2659"></a><a name="INDEX-2660"></a>Put another way, the funny characters <tt class="literal">$</tt>,<tt class="literal">@</tt>, <tt class="literal">%</tt>, or <tt class="literal">*</tt> infront of a variable name tell Perl and its programmers a greatdeal--they each imply a particular set of archetypal behaviors.  Youcan warp those behaviors in various useful ways with<tt class="literal">tie</tt>, by associating the variable with a class thatimplements a new set of behaviors.  For instance, you can create aregular Perl hash, and then <tt class="literal">tie</tt> it to a class thatmakes the hash into a database, so that when you read values from thehash, Perl magically fetches data from an external database file, andwhen you set values in the hash, Perl magically stores data in theexternal database file.  In this case, "magically" means"transparently doing something very complicated".  You know the oldsaying: any technology sufficiently advanced is indistinguishable froma Perl script.  (Seriously, people who play with the guts of Perl use<em class="emphasis">magic</em> as a technical term referring to any extrasemantics attached to variables such as <tt class="literal">%ENV</tt> or<tt class="literal">%SIG</tt>.  Tied variables are just an extension ofthat.)<a name="INDEX-2661"></a></p><p><a name="INDEX-2662"></a><a name="INDEX-2663"></a><a name="INDEX-2664"></a>Perl already has built-in <tt class="literal">dbmopen</tt> and<tt class="literal">dbmclose</tt> functions that magically tie hashvariables to databases, but those functions date back to the days whenPerl had no <tt class="literal">tie</tt>.  Now <tt class="literal">tie</tt>provides a more general mechanism.  In fact, Perl itself implements<tt class="literal">dbmopen</tt> and <tt class="literal">dbmclose</tt> in terms of<tt class="literal">tie</tt>.</p><p><a name="INDEX-2665"></a><a name="INDEX-2666"></a><a name="INDEX-2667"></a>You can <tt class="literal">tie</tt> a scalar, array, hash, or filehandle(via its typeglob) to any class that provides appropriately namedmethods to intercept and emulate normal accesses to those variables.The first of those methods is invoked at the point of the<tt class="literal">tie</tt> itself: tying a variable always invokes aconstructor, which, if successful, returns an object that Perlsquirrels away where you don't see it, down inside the "normal"variable.  You can always retrieve that object later using the<tt class="literal">tied</tt> function on the normal variable:<blockquote><pre class="programlisting">tie <em class="replaceable">VARIABLE</em>, <em class="replaceable">CLASSNAME</em>, <em class="replaceable">LIST</em>;  # binds <em class="replaceable">VARIABLE</em> to <em class="replaceable">CLASSNAME</em>$object = tied <em class="replaceable">VARIABLE</em>;</pre></blockquote>Those two lines are equivalent to:<blockquote><pre class="programlisting">$object = tie <em class="replaceable">VARIABLE</em>, <em class="replaceable">CLASSNAME</em>, <em class="replaceable">LIST</em>;</pre></blockquote>Once it's tied, you treat the normal variable normally, but eachaccess automatically invokes methods on the underlying object; all thecomplexity of the class is hidden behind those method invocations.  Iflater you want to break the association between the variable and theclass, you can <tt class="literal">untie</tt> the variable:<blockquote><pre class="programlisting">untie <em class="replaceable">VARIABLE</em>;</pre></blockquote><a name="INDEX-2668"></a><a name="INDEX-2669"></a>You can almost think of <tt class="literal">tie</tt> as a funny kind of<tt class="literal">bless</tt>, except that it blesses a bare variableinstead of an object reference.  It also can take extra parameters,just as a constructor can--which is not terribly surprising, since itactually does invoke a constructor internally, whose name depends onwhich type of variable you're tying: either<tt class="literal">TIESCALAR</tt>, <tt class="literal">TIEARRAY</tt>,<tt class="literal">TIEHASH</tt>, or<tt class="literal">TIEHANDLE</tt>.<a href="#FOOTNOTE-1">[1]</a> These constructors are invoked as classmethods with the specified <em class="replaceable">CLASSNAME</em> astheir invocant, plus any additional arguments you supplied in<em class="replaceable">LIST</em>.  (The<em class="replaceable">VARIABLE</em> is not passed to the constructor.)<a name="INDEX-2670"></a></p><blockquote class="footnote"><a name="FOOTNOTE-1"></a><p>[1] Since the constructorshave separate names, you could even provide a single class thatimplements all of them.  That would allow you to tie scalars, arrays,hashes, and filehandles all to the same class, although this is notgenerally done, since it would make the other magical methods trickyto write.</p></blockquote><p>These four constructors each return an object in the customaryfashion.  They don't really care whether they were invoked from<tt class="literal">tie</tt>, nor do any of the other methods in the class,since you can always invoke them directly if you'd like.  In onesense, all the magic is in the <tt class="literal">tie</tt>, not in theclass implementing the <tt class="literal">tie</tt>.  It's just an ordinaryclass with funny method names, as far as the class is concerned.(Indeed, some tied modules provide extra methods that aren't visiblethrough the tied variable; these methods must be called explicitly asyou would any other object method.  Such extra methods might provideservices like file locking, transaction protection, or anything elsean instance method might do.)</p><p>So these constructors <tt class="literal">bless</tt> and return an objectreference just as any other constructor would.  That reference neednot refer to the same type of variable as the one being tied; it justhas to be blessed, so that the tied variable can find its way back toyour class for succor.  For instance, our long<tt class="literal">TIEARRAY</tt> example will use a hash-based object, soit can conveniently hold additional information about the array it'semulating.</p><p><a name="INDEX-2671"></a><a name="INDEX-2672"></a><a name="INDEX-2673"></a><a name="INDEX-2674"></a>The <tt class="literal">tie</tt> function will not <tt class="literal">use</tt> or<tt class="literal">require</tt> a module for you--you must do that yourselfexplicitly, if necessary, before calling the<tt class="literal">tie</tt>. (On the other hand, the<tt class="literal">dbmopen</tt> function will, for backward compatibility,attempt to <tt class="literal">use</tt> one or another DBM implementation.But you can preempt its selection with an explicit<tt class="literal">use</tt>, provided the module you <tt class="literal">use</tt>is one of the modules in <tt class="literal">dbmopen</tt>'s list of modulesto try.  See the online docs for the <tt class="literal">AnyDBM_File</tt>module for a fuller explanation.)</p><p><a name="INDEX-2675"></a><a name="INDEX-2676"></a>The methods called by a tied variable have predetermined names like<tt class="literal">FETCH</tt> and <tt class="literal">STORE</tt>, since they'reinvoked implicitly (that is, triggered by particular events) fromwithin the innards of Perl.  These names are in<tt class="literal">ALLCAPS</tt>, a convention we often follow for suchimplicitly called routines.  (Other special names that follow thisconvention include <tt class="literal">BEGIN</tt>, <tt class="literal">CHECK</tt>,<tt class="literal">INIT</tt>, <tt class="literal">END</tt>,<tt class="literal">DESTROY</tt>, and <tt class="literal">AUTOLOAD</tt>, not tomention <tt class="literal">UNIVERSAL-&gt;VERSION</tt>.  In fact, nearly allof Perl's predefined variables and filehandles are in uppercase:<tt class="literal">STDIN</tt>, <tt class="literal">SUPER</tt>,<tt class="literal">CORE</tt>, <tt class="literal">CORE::GLOBAL</tt>,<tt class="literal">DATA</tt>, <tt class="literal">@EXPORT</tt>,<tt class="literal">@INC</tt>, <tt class="literal">@ISA</tt>,<tt class="literal">@ARGV</tt>, and <tt class="literal">%ENV</tt>.  Of course,built-in operators and pragmas go to the opposite extreme and have nocapitals at all.)<a name="INDEX-2677"></a></p><p>The first thing we'll cover is extremely simple: how to tie a scalarvariable.</p><h2 class="sect1">14.1. Tying Scalars</h2><p><a name="INDEX-2678"></a><a name="INDEX-2679"></a><a name="INDEX-2680"></a>To implement a tied scalar, a class must define the following methods:<tt class="literal">TIESCALAR</tt>, <tt class="literal">FETCH</tt>, and<tt class="literal">STORE</tt> (and possibly <tt class="literal">DESTROY</tt>).When you <tt class="literal">tie</tt> a scalar variable, Perl calls<tt class="literal">TIESCALAR</tt>.  When you read the tied variable, itcalls <tt class="literal">FETCH</tt>, and when you assign a value to thevariable, it calls <tt class="literal">STORE</tt>.  If you've kept theobject returned by the initial <tt class="literal">tie</tt> (or if youretrieve it later using <tt class="literal">tied</tt>), you can access theunderlying object yourself--this does not trigger its<tt class="literal">FETCH</tt> or <tt class="literal">STORE</tt> methods.  As anobject, it's not magical at all, but rather quite objective.</p><p><a name="INDEX-2681"></a>If a <tt class="literal">DESTROY</tt> method exists, Perl invokes it whenthe last reference to the tied object disappears, just as for anyother object.  That happens when your program ends or when you call<tt class="literal">untie</tt>, which eliminates the reference used by thetie.  However, <tt class="literal">untie</tt> doesn't eliminate anyoutstanding references you might have stored elsewhere;<tt class="literal">DESTROY</tt> is deferred until those references aregone, too.</p><p>The <tt class="literal">Tie::Scalar</tt> and<tt class="literal">Tie::StdScalar</tt> packages, both found in the standard<tt class="literal">Tie::Scalar</tt> module, provide some simple base classdefinitions if you don't want to define all of these methods yourself.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -