diff options
author | Ilya Zakharevich <ilya@math.berkeley.edu> | 2001-12-31 14:15:39 -0500 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2002-02-14 14:09:10 +0000 |
commit | d5582e24af5719e406cca653747e01382d44c590 (patch) | |
tree | 2340f9c3ae3575916f58f4da01f396a06eec515f /lib/Tie | |
parent | 4fa3f26e6876c535c3a708430a266c39711fbf38 (diff) | |
download | perl-d5582e24af5719e406cca653747e01382d44c590.tar.gz |
tied hashes
Message-ID: <20011231191539.A46@math.ohio-state.edu>
p4raw-id: //depot/perl@14684
Diffstat (limited to 'lib/Tie')
-rw-r--r-- | lib/Tie/Hash.pm | 105 |
1 files changed, 93 insertions, 12 deletions
diff --git a/lib/Tie/Hash.pm b/lib/Tie/Hash.pm index 91ccbee19e..c97e9d078f 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<perltie> for a list of the functions required in order to tie a hash to a package. The basic B<Tie::Hash> package provides a C<new> method, as well -as methods C<TIEHASH>, C<EXISTS> and C<CLEAR>. The B<Tie::StdHash> package -provides most methods required for hashes in L<perltie>. It inherits from -B<Tie::Hash>, and causes tied hashes to behave exactly like standard hashes, -allowing for selective overloading of methods. The C<new> method is provided -as grandfathering in the case a class forgets to include a C<TIEHASH> method. +as methods C<TIEHASH>, C<EXISTS> and C<CLEAR>. The B<Tie::StdHash> and +B<Tie::ExtraHash> packages +provide most methods for hashes described in L<perltie> (the exceptions +are C<UNTIE> and C<DESTROY>). They cause tied hashes to behave exactly like standard hashes, +and allow for selective overwriting of methods. B<Tie::Hash> grandfathers the +C<new> method: it is used if C<TIEHASH> is not defined +in the case a class forgets to include a C<TIEHASH> method. For developers wishing to write their own tied hashes, the required methods are briefly defined below. See the L<perltie> section for more detailed @@ -87,12 +106,63 @@ Clear all values from the tied hash I<this>. =back -=head1 CAVEATS +=head1 Inheriting from B<Tie::StdHash> + +The accessor methods assume that the actual storage for the data in the tied +hash is in the hash referenced by C<tied(%tiedhash)>. Thus overwritten +C<TIEHANDLE> 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<perltie> documentation includes a method called C<DESTROY> as -a necessary method for tied hashes. Neither B<Tie::Hash> nor B<Tie::StdHash> -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<Tie::ExtraHash> + +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<TIEHANDLE> 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<TIEHANDLE> method stores "extra" arguments to tie() starting +from offset 1 in the array referenced by C<tied(%tiedhash)>; this is the +same storage algorithm as in TIEHASH subroutine above. Hence, a typical +package inheriting from B<Tie::ExtraHash> does not need to overwrite this +method. + +=head1 C<UNTIE> and C<DESTROY> + +The methods C<UNTIE> and C<DESTROY> are not defined in B<Tie::Hash>, +B<Tie::StdHash>, or B<Tie::ExtraHash>. Tied hashes do not require +presense of these methods, but if defined, the methods will be called in +proper time, see L<perltie>. + +If needed, these methods should be defined by the package inheriting from +B<Tie::Hash>, B<Tie::StdHash>, or B<Tie::ExtraHash>. =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; |