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

📄 ch14_02.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<html><head><title>Tying Arrays (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="Tying Arrays"><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="ch14_01.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="ch14_01.htm">Chapter 14: Tied Variables</a></td><td align="right" valign="top" width="172"><a href="ch14_03.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">14.2. Tying Arrays</h2><p><a name="INDEX-2702"></a><a name="INDEX-2703"></a><a name="INDEX-2704"></a><a name="INDEX-2705"></a><a name="INDEX-2706"></a><a name="INDEX-2707"></a>A class implementing a tied array must define at least the methods<tt class="literal">TIEARRAY</tt>, <tt class="literal">FETCH</tt>, and<tt class="literal">STORE</tt>.  There are many optional methods: theubiquitous <tt class="literal">DESTROY</tt> method, of course, but also the<tt class="literal">STORESIZE</tt> and <tt class="literal">FETCHSIZE</tt> methodsused to provide <tt class="literal">$#array</tt> and<tt class="literal">scalar(@array)</tt> access.  In addition,<tt class="literal">CLEAR</tt> is triggered when Perl needs to empty thearray, and <tt class="literal">EXTEND</tt> when Perl would have pre-extendedallocation in a real array.</p><p>You may also define the<tt class="literal">POP</tt>, <tt class="literal">PUSH</tt>,<tt class="literal">SHIFT</tt>, <tt class="literal">UNSHIFT</tt>,<tt class="literal">SPLICE</tt>, <tt class="literal">DELETE</tt>, and<tt class="literal">EXISTS</tt> methods if you want the corresponding Perlfunctions to work on the tied array. The <tt class="literal">Tie::Array</tt>class can serve as a base class to implement the first five of thosefunctions in terms of <tt class="literal">FETCH</tt> and<tt class="literal">STORE</tt>.  (<tt class="literal">Tie::Array</tt>'s defaultimplementation of <tt class="literal">DELETE</tt> and<tt class="literal">EXISTS</tt> simply calls <tt class="literal">croak</tt>.)  Aslong as you define <tt class="literal">FETCH</tt> and<tt class="literal">STORE</tt>, it doesn't matter what kind of datastructure your object contains.</p><p>On the other hand, the<tt class="literal">Tie::StdArray</tt> class (defined in the standard<tt class="literal">Tie::Array</tt> module) provides a base class withdefault methods that assume the object contains a regular array.Here's a simple array-tying class that makes use of this.  Because ituses <tt class="literal">Tie::StdArray</tt> as its base class, it only needsto define the methods that should be treated in a nonstandard way.<blockquote><pre class="programlisting">#!/usr/bin/perlpackage ClockArray;use Tie::Array;our @ISA = 'Tie::StdArray';sub FETCH {    my($self,$place) = @_;    $self-&gt;[ $place % 12 ];}sub STORE {    my($self,$place,$value) = @_;    $self-&gt;[ $place % 12 ] = $value;}package main;tie my @array, 'ClockArray';@array = ( "a" ... "z" );print "@array\n";</pre></blockquote>When run, the program prints out "<tt class="literal">y z o p q r s t u v wx</tt>".  This class provides an array with only a dozen slots,like hours of a clock, numbered 0 through 11.  If you ask for the 15tharray index, you really get the 3rd one.  Think of it as a travel aidfor people who haven't learned how to read 24-hour clocks.</p><h3 class="sect2">14.2.1. Array-Tying Methods</h3><p><a name="INDEX-2708"></a><a name="INDEX-2709"></a><a name="INDEX-2710"></a>That's the simple way.  Now for some nitty-gritty details.  Todemonstrate, we'll implement an array whose bounds are fixed at itscreation. If you try to access anything beyond those bounds, anexception is raised.  For example:<blockquote><pre class="programlisting">use BoundedArray;tie @array, "BoundedArray", 2;$array[0] = "fine";$array[1] = "good";$array[2] = "great";$array[3] = "whoa";   # Prohibited; displays an error message.</pre></blockquote>The preamble code for the class is as follows:<blockquote><pre class="programlisting">package BoundedArray;use Carp;use strict;</pre></blockquote>To avoid having to define <tt class="literal">SPLICE</tt> later, we'll inherit from the <tt class="literal">Tie::Array</tt> class:<blockquote><pre class="programlisting">use Tie::Array;our @ISA = ("Tie::Array");</pre></blockquote></p><dl><dt><b><em class="replaceable">CLASSNAME</em><tt class="literal">-&gt;TIEARRAY(</tt><em class="replaceable">LIST</em><tt class="literal">)</tt></b></dt><dd><p> As the constructor for the class,<tt class="literal">TIEARRAY</tt> should return a blessed reference throughwhich the tied array will be emulated.<a name="INDEX-"></a></p><p>In this next example, just to show you that you don't<em class="emphasis">really</em> have to return an array reference, we'llchoose a hash reference to represent our object. A hash works out wellas a generic record type: the value in the hash's"<tt class="literal">BOUND</tt>" key will store the maximum bound allowed,and its "<tt class="literal">DATA</tt>" value will hold the actual data.  Ifsomeone outside the class tries to dereference the object returned(doubtless thinking it an array reference), an exception is raised.<blockquote><pre class="programlisting">sub TIEARRAY {    my $class = shift;    my $bound = shift;    confess "usage: tie(\@ary, 'BoundedArray', max_subscript)"        if @_ || $bound =~ /\D/;    return bless { BOUND =&gt; $bound, DATA =&gt; [] }, $class;}</pre></blockquote>We can now say:<blockquote><pre class="programlisting">tie(@array, "BoundedArray", 3);  # maximum allowable index is 3</pre></blockquote>to ensure that the array will never have more than four elements. Whenever an individual element of the array is accessed or stored,<tt class="literal">FETCH</tt> and <tt class="literal">STORE</tt> will be called just as they were for scalars, butwith an extra index argument.</p></dd><dt><b><em class="replaceable">SELF</em><tt class="literal">-&gt;FETCH(</tt><em class="replaceable">INDEX</em><tt class="literal">)</tt></b></dt><dd><p><a name="INDEX-"></a>This method is run whenever an individual element in the tiedarray is accessed.  It receives one argument after the object: theindex of the value we're trying to fetch.<blockquote><pre class="programlisting">sub FETCH {    my ($self, $index) = @_;    if ($index &gt; $self-&gt;{BOUND}) {        confess "Array OOB: $index &gt; $self-&gt;{BOUND}";    }    return $self-&gt;{DATA}[$index];}</pre></blockquote></p></dd><dt><b><em class="replaceable">SELF</em><tt class="literal">-&gt;STORE(</tt><em class="replaceable">INDEX</em><tt class="literal">,</tt> <em class="replaceable">VALUE</em><tt class="literal">)</tt></b></dt><dd><p><a name="INDEX-"></a>This method is invoked whenever an element in the tied array isset.  It takes two arguments after the object: the index at whichwe're trying to store something and the value we're trying to putthere.  For example:<blockquote><pre class="programlisting">sub STORE {    my($self, $index, $value) = @_;    if ($index &gt; $self-&gt;{BOUND} ) {        confess "Array OOB: $index &gt; $self-&gt;{BOUND}";    }    return $self-&gt;{DATA}[$index] = $value;}</pre></blockquote></p></dd><dt><b><em class="replaceable">SELF</em><tt class="literal">-&gt;DESTROY</tt></b></dt><dd><p>Perl calls this method when the tied variable needs to be destroyed andits memory reclaimed.  This is almost never needed in a language withgarbage collection, so for this example we'll just leave it out.</p></dd><dt><b><em class="replaceable">SELF</em><tt class="literal">-&gt;FETCHSIZE</tt></b></dt><dd><p>The <tt class="literal">FETCHSIZE</tt> method should return the total number of items in the tiedarray associated with <em class="replaceable">SELF</em>.  It's equivalent to <tt class="literal">scalar(@array)</tt>,which is usually equal to <tt class="literal">$#array + 1</tt>.<blockquote><pre class="programlisting">sub FETCHSIZE {    my $self = shift;    return scalar @{$self-&gt;{DATA}};}</pre></blockquote></p></dd><dt><b><em class="replaceable">SELF</em><tt class="literal">-&gt;STORESIZE(</tt><em class="replaceable">COUNT</em><tt class="literal">)</tt></b></dt><dd><p>This method sets the total number of items in the tied array associatedwith <em class="replaceable">SELF</em> to be <em class="replaceable">COUNT</em>.  If the array shrinks, you should removeentries beyond <em class="replaceable">COUNT</em>.  If the array grows, you should make sure thenew positions are undefined.  For our <tt class="literal">BoundedArray</tt> class, we also

⌨️ 快捷键说明

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