This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Unicode: property alias naming cleanup.
[perl5.git] / lib / Tie / RefHash.pm
1 package Tie::RefHash;
2
3 our $VERSION = '1.3_00';
4
5 =head1 NAME
6
7 Tie::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;
14     tie HASHVARIABLE, 'Tie::RefHash::Nestable', LIST;
15
16     untie HASHVARIABLE;
17
18 =head1 DESCRIPTION
19
20 This module provides the ability to use references as hash keys if you
21 first C<tie> the hash variable to this module.  Normally, only the
22 keys of the tied hash itself are preserved as references; to use
23 references as keys in hashes-of-hashes, use Tie::RefHash::Nestable,
24 included as part of Tie::RefHash.
25
26 It is implemented using the standard perl TIEHASH interface.  Please
27 see the C<tie> entry in perlfunc(1) and perltie(1) for more information.
28
29 The Nestable version works by looking for hash references being stored
30 and converting them to tied hashes so that they too can have
31 references as keys.  This will happen without warning whenever you
32 store a reference to one of your own hashes in the tied hash.
33
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
50     tie %h, 'Tie::RefHash::Nestable';
51     $h{$a}->{$b} = 1;
52     for (keys %h, keys %{$h{$a}}) {
53        print ref($_), "\n";
54     }
55
56 =head1 AUTHOR
57
58 Gurusamy Sarathy        gsar@activestate.com
59
60 =head1 VERSION
61
62 Version 1.3
63
64 =head1 SEE ALSO
65
66 perl(1), perlfunc(1), perltie(1)
67
68 =cut
69
70 use Tie::Hash;
71 use vars '@ISA';
72 @ISA = qw(Tie::Hash);
73 use strict;
74
75 sub 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
85 sub FETCH {
86   my($s, $k) = @_;
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   }
98 }
99
100 sub 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
111 sub DELETE {
112   my($s, $k) = @_;
113   (ref $k) ? delete($s->[0]{"$k"}) : delete($s->[1]{$k});
114 }
115
116 sub EXISTS {
117   my($s, $k) = @_;
118   (ref $k) ? exists($s->[0]{"$k"}) : exists($s->[1]{$k});
119 }
120
121 sub FIRSTKEY {
122   my $s = shift;
123   keys %{$s->[0]};      # reset iterator
124   keys %{$s->[1]};      # reset iterator
125   $s->[2] = 0;
126   $s->NEXTKEY;
127 }
128
129 sub 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
143 sub CLEAR {
144   my $s = shift;
145   $s->[2] = 0;
146   %{$s->[0]} = ();
147   %{$s->[1]} = ();
148 }
149
150 package Tie::RefHash::Nestable;
151 use vars '@ISA';
152 @ISA = 'Tie::RefHash';
153
154 sub STORE {
155   my($s, $k, $v) = @_;
156   if (ref($v) eq 'HASH' and not tied %$v) {
157       my @elems = %$v;
158       tie %$v, ref($s), @elems;
159   }
160   $s->SUPER::STORE($k, $v);
161 }
162
163 1;