From: Ilya Zakharevich Date: Mon, 31 Dec 2001 19:15:39 +0000 (-0500) Subject: tied hashes X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d5582e24af5719e406cca653747e01382d44c590;p=p5sagit%2Fp5-mst-13.2.git tied hashes Message-ID: <20011231191539.A46@math.ohio-state.edu> p4raw-id: //depot/perl@14684 --- diff --git a/lib/Tie/Hash.pm b/lib/Tie/Hash.pm index 91ccbee..c97e9d0 100644 --- a/lib/Tie/Hash.pm +++ b/lib/Tie/Hash.pm @@ -4,7 +4,7 @@ our $VERSION = '1.00'; =head1 NAME -Tie::Hash, Tie::StdHash - base class definitions for tied hashes +Tie::Hash, Tie::StdHash, Tie::ExtraHash - base class definitions for tied hashes =head1 SYNOPSIS @@ -23,24 +23,43 @@ Tie::Hash, Tie::StdHash - base class definitions for tied hashes @ISA = (Tie::StdHash); # All methods provided by default, define only those needing overrides + # Accessors access the storage in %{$_[0]}; + # TIEHANDLE should return a reference to the actual storage sub DELETE { ... } + package NewExtraHash; + require Tie::Hash; + + @ISA = (Tie::ExtraHash); + + # All methods provided by default, define only those needing overrides + # Accessors access the storage in %{$_[0][0]}; + # TIEHANDLE should return an array reference with the first element being + # the reference to the actual storage + sub DELETE { + $_[0][1]->('del', $_[0][0], $_[1]); # Call the report writer + delete $_[0][0]->{$_[1]}; # $_[0]->SUPER::DELETE($_[1]) } + package main; tie %new_hash, 'NewHash'; tie %new_std_hash, 'NewStdHash'; + tie %new_extra_hash, 'NewExtraHash', + sub {warn "Doing \U$_[1]\E of $_[2].\n"}; =head1 DESCRIPTION This module provides some skeletal methods for hash-tying classes. See L for a list of the functions required in order to tie a hash to a package. The basic B package provides a C method, as well -as methods C, C and C. The B package -provides most methods required for hashes in L. It inherits from -B, and causes tied hashes to behave exactly like standard hashes, -allowing for selective overloading of methods. The C method is provided -as grandfathering in the case a class forgets to include a C method. +as methods C, C and C. The B and +B packages +provide most methods for hashes described in L (the exceptions +are C and C). They cause tied hashes to behave exactly like standard hashes, +and allow for selective overwriting of methods. B grandfathers the +C method: it is used if C is not defined +in the case a class forgets to include a C method. For developers wishing to write their own tied hashes, the required methods are briefly defined below. See the L section for more detailed @@ -87,12 +106,63 @@ Clear all values from the tied hash I. =back -=head1 CAVEATS +=head1 Inheriting from B + +The accessor methods assume that the actual storage for the data in the tied +hash is in the hash referenced by C. Thus overwritten +C method should return a hash reference, and the remaining methods +should operate on the hash referenced by the first argument: + + package ReportHash; + our @ISA = 'Tie::StdHash'; + + sub TIEHASH { + my $storage = bless {}, shift; + warn "New ReportHash created, stored in $storage.\n"; + $storage + } + sub STORE { + warn "Storing data with key $_[1] at $_[0].\n"; + $_[0]{$_[1]} = $_[2] + } + -The L documentation includes a method called C as -a necessary method for tied hashes. Neither B nor B -define a default for this method. This is a standard for class packages, -but may be omitted in favor of a simple default. +=head1 Inheriting from B + +The accessor methods assume that the actual storage for the data in the tied +hash is in the hash referenced by C<(tied(%tiedhash))[0]>. Thus overwritten +C method should return an array reference with the first +element being a hash reference, and the remaining methods should operate on the +hash C<< %{ $_[0]->[0] }>>: + + package ReportHash; + our @ISA = 'Tie::StdHash'; + + sub TIEHASH { + my $storage = bless {}, shift; + warn "New ReportHash created, stored in $storage.\n"; + [$storage, @_] + } + sub STORE { + warn "Storing data with key $_[1] at $_[0].\n"; + $_[0][0]{$_[1]} = $_[2] + } + +The default C method stores "extra" arguments to tie() starting +from offset 1 in the array referenced by C; this is the +same storage algorithm as in TIEHASH subroutine above. Hence, a typical +package inheriting from B does not need to overwrite this +method. + +=head1 C and C + +The methods C and C are not defined in B, +B, or B. Tied hashes do not require +presense of these methods, but if defined, the methods will be called in +proper time, see L. + +If needed, these methods should be defined by the package inheriting from +B, B, or B. =head1 MORE INFORMATION @@ -148,7 +218,7 @@ sub CLEAR { # alter some parts of their behaviour. package Tie::StdHash; -@ISA = qw(Tie::Hash); +# @ISA = qw(Tie::Hash); # would inherit new() only sub TIEHASH { bless {}, $_[0] } sub STORE { $_[0]->{$_[1]} = $_[2] } @@ -159,4 +229,15 @@ sub EXISTS { exists $_[0]->{$_[1]} } sub DELETE { delete $_[0]->{$_[1]} } sub CLEAR { %{$_[0]} = () } +package Tie::ExtraHash; + +sub TIEHASH { my $p = shift; bless [{}, @_], $p } +sub STORE { $_[0][0]{$_[1]} = $_[2] } +sub FETCH { $_[0][0]{$_[1]} } +sub FIRSTKEY { my $a = scalar keys %{$_[0][0]}; each %{$_[0][0]} } +sub NEXTKEY { each %{$_[0][0]} } +sub EXISTS { exists $_[0][0]->{$_[1]} } +sub DELETE { delete $_[0][0]->{$_[1]} } +sub CLEAR { %{$_[0][0]} = () } + 1; diff --git a/pod/perltie.pod b/pod/perltie.pod index f959367..adc557d 100644 --- a/pod/perltie.pod +++ b/pod/perltie.pod @@ -161,7 +161,7 @@ argument--the new value the user is trying to assign. This method will be triggered when the C occurs. This can be useful if the class needs to know when no further calls will be made. (Except DESTROY -of course.) See below for more details. +of course.) See L Gotcha> below for more details. =item DESTROY this @@ -452,7 +452,7 @@ In our example, we'll use a little shortcut if there is a I: =item UNTIE this -Will be called when C happens. (See below.) +Will be called when C happens. (See L Gotcha> below.) =item DESTROY this @@ -475,7 +475,7 @@ the keys. UNTIE is called when C happens, and DESTROY is called when the tied variable is garbage collected. If this seems like a lot, then feel free to inherit from merely the -standard Tie::Hash module for most of your methods, redefining only the +standard Tie::StdHash module for most of your methods, redefining only the interesting ones. See L for details. Remember that Perl distinguishes between a key not existing in the hash, @@ -756,7 +756,7 @@ thing, but we'll have to go through the LIST field indirectly. =item UNTIE this -This is called when C occurs. +This is called when C occurs. See L Gotcha> below. =item DESTROY this @@ -880,7 +880,8 @@ function. =item UNTIE this As with the other types of ties, this method will be called when C happens. -It may be appropriate to "auto CLOSE" when this occurs. +It may be appropriate to "auto CLOSE" when this occurs. See +L Gotcha> below. =item DESTROY this @@ -903,7 +904,7 @@ Here's how to use our little example: =head2 UNTIE this You can define for all tie types an UNTIE method that will be called -at untie(). +at untie(). See L Gotcha> below. =head2 The C Gotcha