File Coverage

blib/lib/Tie/Hash/TwoWay.pm
Criterion Covered Total %
statement 56 64 87.5
branch 16 24 66.6
condition 6 18 33.3
subroutine 12 14 85.7
pod n/a
total 90 120 75.0


line stmt bran cond sub pod time code
1             # DESCRIPTION Tie::Hash::TwoWay is a Perl module for associative
2             # two-way mapping between two disjoint sets. Elements of the sets
3             # are treated as hash keys.
4             #
5             # AUTHOR
6             # Teodor Zlatanov
7             #
8             # COPYRIGHT
9             # Copyright (C) 2001, 2005 Gold Software Systems
10             #
11             # This script is free software; you can redistribute it and/or
12             # modify it under the same terms as Perl itself.
13             #
14              
15             package Tie::Hash::TwoWay;
16              
17             require 5.005_62;
18 1     1   1279 use strict;
  1         2  
  1         42  
19 1     1   7 use vars qw($VERSION @ISA);
  1         1  
  1         80  
20 1     1   1309 use Tie::Hash;
  1         1394  
  1         29  
21 1     1   7 use Carp;
  1         2  
  1         135  
22              
23 1     1   7 use constant PRIMARY => 0;
  1         2  
  1         216  
24 1     1   7 use constant SECONDARY => 1;
  1         2  
  1         842  
25              
26             $VERSION = sprintf "%d.%02d", '$Revision 1.8 $' =~ /(\d+)\.(\d+)/;
27             @ISA = qw/Tie::StdHash/;
28              
29             # Preloaded methods go here.
30              
31             sub STORE
32             {
33 3     3   112 my ($self, $key, $value) = @_;
34 3         4 my $val_array_ref;
35              
36 3 100       9 if (ref $value eq 'ARRAY') # array refs can be recognized
37             {
38 2         3 $val_array_ref = $value;
39             }
40             else # everything else gets converted to array refs
41             {
42 1         3 $val_array_ref = [ $value ];
43             }
44              
45             # add the values in the passed array to the primary and secondary hashes
46 3         7 foreach my $value (@$val_array_ref)
47             {
48 7         29 $self->{SECONDARY}->{$value}->{$key} = 1;
49 7         17 $self->{PRIMARY}->{$key}->{$value} = 1;
50             }
51              
52 3         8 return 1;
53             }
54              
55             # return the primary or secondary key, in that order (duplicate keys
56             # are not detected here)
57             sub FETCH
58             {
59 4     4   119 my ($self, $key) = @_;
60              
61 4 100       14 exists $self->{PRIMARY}->{$key} &&
62             return $self->{PRIMARY}->{$key};
63              
64 3 50       16 exists $self->{SECONDARY}->{$key} &&
65             return $self->{SECONDARY}->{$key};
66              
67 0         0 return undef;
68             }
69              
70             # return the primary or secondary key existence, in that order
71             # (duplicate keys are not detected here)
72             sub EXISTS
73             {
74 3     3   44 my ($self, $key) = @_;
75              
76 3 50 33     20 return undef unless (exists $self->{PRIMARY} &&
77             exists $self->{SECONDARY});
78            
79 3   66     21 return (exists $self->{PRIMARY}->{$key} ||
80             exists $self->{SECONDARY}->{$key});
81             }
82              
83             # delete the primary or secondary key, in that order (duplicate keys
84             # are not detected here)
85             sub DELETE
86             {
87 5     5   67 my ($self, $key) = @_;
88              
89 5 50 33     24 return undef unless (exists $self->{PRIMARY} &&
90             exists $self->{SECONDARY});
91              
92             # make sure to delete reverse associations as well
93 5 100       14 if (exists $self->{PRIMARY}->{$key})
94             {
95              
96 1         1 foreach (keys %{$self->{SECONDARY}})
  1         6  
97             {
98 6         9 delete $self->{SECONDARY}->{$_}->{$key};
99 6         19 delete $self->{SECONDARY}->{$_}
100 6 100       5 unless scalar keys %{$self->{SECONDARY}->{$_}};
101             }
102              
103 1         5 return delete $self->{PRIMARY}->{$key};
104             }
105            
106 4 50       10 if (exists $self->{SECONDARY}->{$key})
107             {
108              
109 4         5 foreach (keys %{$self->{PRIMARY}})
  4         8  
110             {
111 7         9 delete $self->{PRIMARY}->{$_}->{$key};
112 7         22 delete $self->{PRIMARY}->{$_}
113 7 100       6 unless scalar keys %{$self->{PRIMARY}->{$_}};
114             }
115              
116 4         12 return delete $self->{SECONDARY}->{$key};
117             }
118            
119             }
120              
121             sub CLEAR
122             {
123 0     0   0 my ($self, $key) = @_;
124              
125 0         0 %$self = (); # clear the whole hash
126              
127 0         0 return 1;
128             }
129              
130             sub FIRSTKEY
131             {
132 1     1   7 my ($self) = @_;
133              
134 1 50 33     15 return undef unless (exists $self->{PRIMARY} &&
135             exists $self->{SECONDARY});
136            
137 1         2 return each %{$self->{PRIMARY}};
  1         3  
138             }
139              
140             sub NEXTKEY
141             {
142 0     0   0 my ($self, $lastkey) = @_;
143              
144 0 0 0     0 return undef unless (exists $self->{PRIMARY} &&
145             exists $self->{SECONDARY});
146            
147 0         0 return each %{$self->{PRIMARY}};
  0         0  
148             }
149              
150             sub SCALAR
151             {
152 1     1   25 my ($self) = @_;
153              
154 1 50 33     8 return undef unless (exists $self->{PRIMARY} &&
155             exists $self->{SECONDARY});
156            
157 1         3 return $self->{SECONDARY};
158             }
159              
160             1;
161             __END__