File Coverage

blib/lib/Hash/Iterator.pm
Criterion Covered Total %
statement 76 90 84.4
branch 18 30 60.0
condition 2 3 66.6
subroutine 16 21 76.1
pod 0 9 0.0
total 112 153 73.2


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