File Coverage

lib/Data/AsObject/Hash.pm
Criterion Covered Total %
statement 64 70 91.4
branch 23 36 63.8
condition 9 24 37.5
subroutine 17 17 100.0
pod 0 1 0.0
total 113 148 76.3


line stmt bran cond sub pod time code
1             package Data::AsObject::Hash;
2             BEGIN {
3 4     4   78 $Data::AsObject::Hash::VERSION = '0.07';
4             }
5              
6             # ABSTRACT: Base class for Data::AsObject hashrefs
7              
8 4     4   21 use strict;
  4         7  
  4         126  
9 4     4   18 use warnings;
  4         7  
  4         93  
10 4     4   20 use Carp;
  4         7  
  4         230  
11 4     4   22 use Data::AsObject ();
  4         8  
  4         116  
12 4     4   3790 use namespace::clean -except => [qw/AUTOLOAD/];
  4         80687  
  4         40  
13              
14             our $AUTOLOAD;
15              
16             sub can {
17 5 50   5 0 625 if(@_ != 2) {
18 0         0 local $AUTOLOAD = ref($_[0]) .'::can';
19 0         0 return $_[0]->AUTOLOAD(@_);
20             }
21              
22 5         26 my($self, $key) = @_;
23 5 100       72 return unless( exists $self->{$key} );
24 2     2   20 return sub { __get_data($self, $key) };
  2         9  
25             }
26              
27             sub AUTOLOAD {
28 19     19   20107 my $self = shift;
29 19         28 my $index = shift;
30 19         42 my $data;
31              
32 19         27 my $key = $AUTOLOAD;
33 19         96 $key =~ s/.*:://;
34 19         31 undef $AUTOLOAD;
35              
36 19 0 33     101 if ($key eq "can" && defined $index && $index != /\d+/) {
      33        
37 0         0 return undef;
38             }
39              
40 19 0 33     58 if ($key eq "isa" && defined $index && $index != /\d+/) {
      33        
41 0 0 0     0 $index eq ref($self) or
    0          
42             $index eq "Data::AsObject::Hash" or
43             $index eq "UNIVERSAL"
44             ? return 1
45             : return 0;
46             }
47              
48 19         43 return __get_data($self, $key, $index);
49             }
50              
51             sub __get_data {
52 21     21   38 my ($self, $key, $index) = @_;
53 21 100       91 my $data = exists $self->{$key} ? $self->{$key} : __guess_data($self, $key);
54 21 50       124 my $mode = ref($self) =~ /^.*::(\w+)$/ ? $1 : '';
55              
56 21 100       61 if ( !$data ) {
57 4 50       10 return if $key eq "DESTROY";
58              
59 4         10 my $msg = "Attempting to access non-existing hash key $key!";
60              
61 4 100       23 carp $msg if $mode eq 'Loose';
62 4 100       297 croak $msg if $mode eq 'Strict';
63 2         12 return;
64             }
65              
66 17 50 66     83 if (
      66        
      33        
67             defined $index
68             && $index =~ /\d+/
69             && $Data::AsObject::__check_type->($data) eq "ARRAY"
70             && exists $data->[$index]
71             )
72             {
73 5         10 $data = $data->[$index];
74             }
75              
76 17 100       48 if ( $Data::AsObject::__check_type->($data) eq "ARRAY" ) {
    100          
77 4         18 bless $data, "Data::AsObject::Array::$mode";
78             } elsif ( $Data::AsObject::__check_type->($data) eq "HASH" ) {
79 2         12 bless $data, "Data::AsObject::Hash::$mode";
80             }
81              
82 17         123 return $data;
83             }
84              
85             sub __guess_data {
86 6     6   8 my $self = shift;
87 6         11 my $key_regex = shift;
88 6         16 my $has_colon_or_dash = $key_regex =~ s/_/[-:]/g;
89 6 100       105 my @matches = grep(/$key_regex/, keys %$self) if $has_colon_or_dash;
90              
91 6 100       24 if ( @matches == 1 ) {
    50          
92 2         6 return $self->{$matches[0]};
93             } elsif ( @matches > 1 ) {
94 0         0 carp "Attempt to disambiguate hash key $key_regex returns multiple matches!";
95 0         0 return $self->{$matches[0]};
96             }
97              
98 4         10 return;
99             }
100              
101              
102             package Data::AsObject::Hash::Strict;
103             BEGIN {
104 4     4   3610 $Data::AsObject::Hash::Strict::VERSION = '0.07';
105             }
106 4     4   35 use base 'Data::AsObject::Hash';
  4         14  
  4         429  
107              
108             package Data::AsObject::Hash::Loose;
109             BEGIN {
110 4     4   88 $Data::AsObject::Hash::Loose::VERSION = '0.07';
111             }
112 4     4   19 use base 'Data::AsObject::Hash';
  4         8  
  4         344  
113              
114             package Data::AsObject::Hash::Silent;
115             BEGIN {
116 4     4   77 $Data::AsObject::Hash::Silent::VERSION = '0.07';
117             }
118 4     4   20 use base 'Data::AsObject::Hash';
  4         11  
  4         308  
119              
120             1;
121              
122              
123             __END__