File Coverage

blib/lib/Hash/Iterator.pm
Criterion Covered Total %
statement 76 88 86.3
branch 18 30 60.0
condition 2 3 66.6
subroutine 16 21 76.1
pod 8 9 88.8
total 120 151 79.4


line stmt bran cond sub pod time code
1 1     1   48281 use utf8;
  1         19  
  1         4  
2              
3             package Hash::Iterator;
4              
5 1     1   32 use strict;
  1         2  
  1         20  
6 1     1   4 use warnings FATAL => 'all';
  1         1  
  1         33  
7 1     1   5 use Carp ();
  1         1  
  1         17  
8              
9 1     1   4 use constant MsgEmptyHash => 'the iterator has no values';
  1         1  
  1         102  
10 1     1   5 use constant TRUE => 1;
  1         2  
  1         40  
11 1     1   5 use constant FALSE => 0;
  1         2  
  1         633  
12              
13             our $VERSION = '0.002';
14              
15             sub new {
16 8     8 1 2501 my $class = shift;
17              
18 8 50       39 Carp::croak("new() requires key-value pairs")
19             unless @_ % 2 == 0;
20              
21 8         19 my ( @keys, %data, $object );
22              
23 8         29 while (@_) {
24 13         27 my $k = shift;
25 13         31 push @keys, $k;
26 13         49 $data{$k} = shift;
27             }
28              
29             $object = {
30 8         59 Keys => [@keys],
31             Data => {%data},
32             LengthKeys => $#keys,
33             CurrentState => -1,
34             PreviousState => -1,
35             };
36              
37 8         66 return bless $object, $class;
38             }
39              
40             sub done {
41 0     0 1 0 my $self = shift;
42              
43 0 0       0 return ( $self->_get_position == $self->_get_LengthKeys )
44             ? TRUE
45             : FALSE;
46             }
47              
48             sub next {
49 15     15 1 5013 my $self = shift;
50              
51 15 100       31 unless ( %{ $self->{Data} } ) {
  15         61  
52 1         212 Carp::croak(MsgEmptyHash);
53             }
54              
55 14 100       48 if ( $self->{LengthKeys} > $self->{CurrentState} ) {
56 12         29 $self->{PreviousState} = $self->{CurrentState};
57 12         41 $self->{CurrentState}++;
58             }
59             else {
60 2         9 return 0;
61             }
62 12         34 return 1;
63             }
64              
65             sub previous {
66 2     2 1 1414 my $self = shift;
67              
68 2 100 66     18 if ( ( int $self->{CurrentState} != -1 )
69             and ( int $self->{PreviousState} != -1 ) )
70             {
71 1         4 $self->{CurrentState} = $self->{PreviousState};
72 1         4 $self->{PreviousState}--;
73              
74 1         5 return 1;
75             }
76 1         5 return undef;
77             }
78              
79             sub peek_key {
80 9     9 1 30 my $self = shift;
81 9         24 my $key = $self->_get_key;
82              
83 9 50       57 return $key if $key;
84 0         0 return undef;
85             }
86              
87             sub peek_value {
88 8     8 1 40 my $self = shift;
89 8         19 my $value = $self->_get_value;
90              
91 8 100       36 if ( ref $value eq 'HASH' ) {
    100          
92 2         19 return \%$value;
93             }
94             elsif ( ref $value eq 'ARRAY' ) {
95 2         16 return \@$value;
96             }
97             else {
98 4         23 return $value;
99             }
100             }
101              
102             sub is_ref {
103 11     11 1 4485 my ( $self, $ref ) = @_;
104 11         36 my $value = $self->_get_value;
105              
106 11 100       37 if ( ref $value eq $ref ) {
107 4         23 return 1;
108             }
109 7         23 return;
110             }
111              
112             sub get_data {
113 0     0 0 0 my $self = shift;
114             return wantarray
115 0 0       0 ? @{ $self->{Data} }
  0         0  
116             : $self->_get_LengthKeys;
117             }
118              
119             sub get_keys {
120 0     0 1 0 my $self = shift;
121             return wantarray
122 0 0       0 ? @{ $self->{Keys} }
  0         0  
123             : $self->_get_LengthKeys;
124             }
125              
126             sub _get_value {
127 19     19   43 my $self = shift;
128              
129 19         37 my ( $CurrentValue, $CurrentKey );
130 19         38 eval {
131 19         32 $CurrentKey = ${ $self->{Keys} }[ $self->_get_position ];
  19         78  
132 19         40 $CurrentValue = ${ $self->{Data} }{$CurrentKey};
  19         53  
133             };
134 19 50       57 Carp::croak($@) if $@;
135              
136 19 50       69 return $CurrentValue if $CurrentValue;
137 0         0 return undef;
138             }
139              
140             sub _get_key {
141 9     9   18 my $self = shift;
142              
143 9         17 my $curKey;
144 9         20 eval { $curKey = ${ $self->{Keys} }[ $self->_get_position ]; };
  9         16  
  9         29  
145 9 50       29 Carp::croak($@) if $@;
146              
147 9 50       34 return $curKey if $curKey;
148             }
149              
150 28     28   77 sub _get_position { shift->{CurrentState} }
151 0     0     sub _get_PreviousState { shift->{PreviousState} }
152 0     0     sub _get_LengthKeys { shift->{LengthKeys} }
153              
154             1;
155              
156             __END__