Once again syncing after too long an absence
[p5sagit/p5-mst-13.2.git] / lib / Tie / RefHash.pm
CommitLineData
5f05dabc 1package Tie::RefHash;
2
0e06870b 3our $VERSION = '1.21';
4
5f05dabc 5=head1 NAME
6
7Tie::RefHash - use references as hash keys
8
9=head1 SYNOPSIS
10
11 require 5.004;
12 use Tie::RefHash;
13 tie HASHVARIABLE, 'Tie::RefHash', LIST;
0e06870b 14 tie HASHVARIABLE, 'Tie::RefHash::Nestable', LIST;
5f05dabc 15
16 untie HASHVARIABLE;
17
18=head1 DESCRIPTION
19
0e06870b 20This module provides the ability to use references as hash keys if you
21first C<tie> the hash variable to this module. Normally, only the
22keys of the tied hash itself are preserved as references; to use
23references as keys in hashes-of-hashes, use Tie::RefHash::Nestable,
24included as part of Tie::Hash.
5f05dabc 25
26It is implemented using the standard perl TIEHASH interface. Please
27see the C<tie> entry in perlfunc(1) and perltie(1) for more information.
28
0e06870b 29The Nestable version works by looking for hash references being stored
30and converting them to tied hashes so that they too can have
31references as keys. This will happen without warning whenever you
32store a reference to one of your own hashes in the tied hash.
33
5f05dabc 34=head1 EXAMPLE
35
36 use Tie::RefHash;
37 tie %h, 'Tie::RefHash';
38 $a = [];
39 $b = {};
40 $c = \*main;
41 $d = \"gunk";
42 $e = sub { 'foo' };
43 %h = ($a => 1, $b => 2, $c => 3, $d => 4, $e => 5);
44 $a->[0] = 'foo';
45 $b->{foo} = 'bar';
46 for (keys %h) {
47 print ref($_), "\n";
48 }
49
0e06870b 50 tie %h, 'Tie::RefHash::Nestable';
51 $h{$a}->{$b} = 1;
52 for (keys %h, keys %{$h{$a}}) {
53 print ref($_), "\n";
54 }
5f05dabc 55
56=head1 AUTHOR
57
da41ffc5 58Gurusamy Sarathy gsar@activestate.com
5f05dabc 59
60=head1 VERSION
61
da41ffc5 62Version 1.21 22 Jun 1999
5f05dabc 63
64=head1 SEE ALSO
65
66perl(1), perlfunc(1), perltie(1)
67
68=cut
69
70require 5.003_11;
71use Tie::Hash;
72@ISA = qw(Tie::Hash);
73use strict;
74
75sub TIEHASH {
76 my $c = shift;
77 my $s = [];
78 bless $s, $c;
79 while (@_) {
80 $s->STORE(shift, shift);
81 }
82 return $s;
83}
84
85sub FETCH {
86 my($s, $k) = @_;
0e06870b 87 if (ref $k) {
88 if (defined $s->[0]{"$k"}) {
89 $s->[0]{"$k"}[1];
90 }
91 else {
92 undef;
93 }
94 }
95 else {
96 $s->[1]{$k};
97 }
5f05dabc 98}
99
100sub STORE {
101 my($s, $k, $v) = @_;
102 if (ref $k) {
103 $s->[0]{"$k"} = [$k, $v];
104 }
105 else {
106 $s->[1]{$k} = $v;
107 }
108 $v;
109}
110
111sub DELETE {
112 my($s, $k) = @_;
113 (ref $k) ? delete($s->[0]{"$k"}) : delete($s->[1]{$k});
114}
115
116sub EXISTS {
117 my($s, $k) = @_;
118 (ref $k) ? exists($s->[0]{"$k"}) : exists($s->[1]{$k});
119}
120
121sub FIRSTKEY {
122 my $s = shift;
da41ffc5 123 keys %{$s->[0]}; # reset iterator
124 keys %{$s->[1]}; # reset iterator
5f05dabc 125 $s->[2] = 0;
126 $s->NEXTKEY;
127}
128
129sub NEXTKEY {
130 my $s = shift;
131 my ($k, $v);
132 if (!$s->[2]) {
133 if (($k, $v) = each %{$s->[0]}) {
134 return $s->[0]{"$k"}[0];
135 }
136 else {
137 $s->[2] = 1;
138 }
139 }
140 return each %{$s->[1]};
141}
142
143sub CLEAR {
144 my $s = shift;
145 $s->[2] = 0;
146 %{$s->[0]} = ();
147 %{$s->[1]} = ();
148}
149
0e06870b 150package Tie::RefHash::Nestable;
151use vars '@ISA'; @ISA = qw(Tie::RefHash);
152
153sub STORE {
154 my($s, $k, $v) = @_;
155 if (ref($v) eq 'HASH' and not tied %$v) {
156 my @elems = %$v;
157 tie %$v, ref($s), @elems;
158 }
159 $s->SUPER::STORE($k, $v);
160}
161
5f05dabc 1621;