File Coverage

blib/lib/Thesaurus.pm
Criterion Covered Total %
statement 67 69 97.1
branch 14 20 70.0
condition n/a
subroutine 13 13 100.0
pod 5 5 100.0
total 99 107 92.5


line stmt bran cond sub pod time code
1             package Thesaurus;
2              
3 2     2   1504 use strict;
  2         5  
  2         84  
4              
5 2     2   13 use vars qw[$VERSION];
  2         2  
  2         120  
6              
7             $VERSION = '0.23';
8              
9 2     2   3826 use Params::Validate qw( validate_with BOOLEAN );
  2         36155  
  2         1780  
10              
11             sub new
12             {
13 6     6 1 1426 my $class = shift;
14 6         212 my %p = validate_with( params => \@_,
15             spec => { ignore_case => { type => BOOLEAN, default => 0 },
16             },
17             allow_extra => 1,
18             );
19              
20 6         59 my $self = bless { params => { ignore_case => delete $p{ignore_case},
21             }
22             }, $class;
23              
24 6         30 $self->_init(%p);
25              
26 6         29 return bless $self, $class;
27             }
28              
29             sub _init
30             {
31 2     2   4 my $self = shift;
32              
33 2         9 $self->{data} = {};
34             }
35              
36             sub add
37             {
38 9     9 1 50 my $self = shift;
39              
40 9         109 foreach my $list (@_)
41             {
42 16         44 $self->_add_list($list);
43             }
44             }
45              
46             sub _add_list
47             {
48 16     16   22 my $self = shift;
49 16         20 my $list = shift;
50              
51 16         36 my %items = $self->_hash_from_list($list);
52              
53 16         68 while ( my ($k, $v) = each %items )
54             {
55 72         351 $self->{data}{$k} = $v;
56             }
57             }
58              
59             sub _hash_from_list
60             {
61 16     16   21 my $self = shift;
62 16         18 my $list = shift;
63              
64             # if we have any of these already, we need to create new lists for
65             # them
66 64         156 my @new =
67 16         35 map { $self->find($_) } $self->_normalize_list($list);
68              
69             # return a unique list
70 16         26 my @unique = keys %{ { map { $_ => 1 } @new, @$list } };
  16         25  
  76         214  
71              
72             # a hash of keys to values
73 16 100       55 return map { ( $self->{params}{ignore_case} ? lc $_ : $_ ) => \@unique } @unique;
  76         253  
74             }
75              
76             sub find
77             {
78 79     79 1 7780 my $self = shift;
79              
80 79         153 my $lists = $self->_find(@_);
81              
82 79 50       147 if (@_ > 1)
83             {
84 0 0       0 return unless %$lists;
85 0         0 return %$lists;
86             }
87             else
88             {
89 79 50       221 return unless exists $lists->{ $_[0] };
90 79         81 return @{ $lists->{ $_[0] } };
  79         378  
91             }
92             }
93              
94             sub _find
95             {
96 79     79   662 my $self = shift;
97              
98 79         86 my %lists;
99 79         126 foreach my $key (@_)
100             {
101 79 100       201 my $search_key = $self->{params}{ignore_case} ? lc $key : $key;
102              
103             # ignore duplicates
104 79 50       160 next if exists $lists{$key};
105              
106             # Anonymize to keep people away from our lists!
107 13         64 $lists{$key} =
108 79 100       332 exists $self->{data}{$search_key} ? [ @{ $self->{data}{$search_key} } ] : [];
109             }
110              
111 79         168 return \%lists;
112             }
113              
114             sub delete
115             {
116 2     2 1 1267 my $self = shift;
117              
118 2         12 foreach my $item ( $self->_normalize_list(\@_) )
119             {
120 2 50       13 next unless exists $self->{data}{$item};
121              
122 2         4 foreach my $key ( @{ $self->{data}{$item} } )
  2         9  
123             {
124 12         47 delete $self->{data}{$key};
125             }
126             }
127             }
128              
129             sub all
130             {
131 1     1 1 4 my $self = shift;
132              
133 1         2 my (%done, @data);
134 1         2 foreach my $key ( keys %{ $self->{data} } )
  1         6  
135             {
136 6 100       16 next if exists $done{$key};
137              
138 2         4 @done{ @{ $self->{data}{$key} } } = ();
  2         7  
139              
140 2         7 push @data, $self->{data}{$key};
141             }
142              
143             return @data
144 1         6 }
145              
146             sub _normalize_list
147             {
148 18     18   25 my $self = shift;
149 18         22 my $list = shift;
150              
151 18 100       58 return map { lc } @$list if $self->{params}{ignore_case};
  30         61  
152 10         34 return @$list;
153             }
154              
155             1;
156              
157             __END__