File Coverage

blib/lib/Hash/Compact.pm
Criterion Covered Total %
statement 63 65 96.9
branch 16 18 88.8
condition 22 28 78.5
subroutine 11 12 91.6
pod 6 7 85.7
total 118 130 90.7


line stmt bran cond sub pod time code
1             package Hash::Compact;
2 2     2   62241 use 5.008001;
  2         7  
  2         70  
3 2     2   11 use strict;
  2         3  
  2         67  
4 2     2   10 use warnings;
  2         7  
  2         146  
5 2     2   11 use Carp qw(croak);
  2         3  
  2         145  
6 2     2   11 use Scalar::Util qw(blessed);
  2         3  
  2         1695  
7              
8             our $VERSION = '0.06';
9              
10             sub new {
11 16     16 1 12801 my $class = shift;
12 16 100 66     99 my $options = @_ > 1 && (ref $_[-1] || '') eq 'HASH' ? pop : {};
13 16         52 my $self = bless { __HASH_COMPACT_OPTIONS__ => $options }, $class;
14 16   100     39 my $args = shift || {};
15              
16 16 50 50     52 croak '$args must be a hash-ref'
17             if (ref $args || '') ne 'HASH';
18              
19 16         56 while (my ($key, $value) = each %$args) {
20 12         30 $self->param($key, $value);
21             }
22              
23 16         32 $self;
24             }
25              
26 65     65 0 750 sub options { $_[0]->{__HASH_COMPACT_OPTIONS__} }
27              
28             sub keys {
29 10     10 1 47 my $self = shift;
30 10         10 my %alias_map;
31             my @defaults;
32              
33 10         10 for my $key (CORE::keys %{$self->options}) {
  10         17  
34 10 100       13 if (my $raw = $self->options->{$key}{alias_for}) {
35 6         9 $alias_map{$raw} = $key;
36             }
37 10 100       16 if ($self->options->{$key}{default}) {
38 7         17 push @defaults, $key;
39             }
40             }
41              
42 10         14 my %seen;
43 11         59 grep { !$seen{$_}++ } map {
  11         13  
44 21         46 my $key = $_;
45 11 100       30 my $original_key = $alias_map{$key} ? $alias_map{$key} : $key;
46 10         23 } grep { $_ ne '__HASH_COMPACT_OPTIONS__' } (keys %$self, @defaults);
47             }
48              
49             sub param {
50 35     35 1 6439 my $self = shift;
51 35         37 my $value;
52              
53 35 100       66 if (@_ > 1) {
54 19 50       44 croak 'incorrect key/value pair'
55             if @_ % 2;
56              
57 19         39 my %args = @_;
58 19         49 while (my ($key, $value) = each %args) {
59 19   100     34 my $option = $self->options->{$key} || {};
60 19   66     53 $key = $option->{alias_for} || $key;
61              
62 19 100 66     138 if (defined $value && !ref $value && $value eq ($option->{default} || '')) {
      100        
      100        
63 5         21 delete $self->{$key};
64             }
65             else {
66 14         85 $self->{$key} = $value;
67             }
68             }
69             }
70             else {
71 16         17 my $key = shift;
72 16   100     231 my $option = $self->options->{$key} || {};
73              
74 16   66     258 $value = $self->{$option->{alias_for} || $key} || $option->{default};
75             }
76              
77 35         106 $value;
78             }
79              
80             sub to_hash {
81 0     0 1 0 warn 'to_hash() method will be deprecated at later version. use compact() instead';
82 0         0 $_[0]->compact;
83             }
84              
85             sub compact {
86 11     11 1 1014 my $self = shift;
87              
88             +{
89 15         19 map {
90 26         85 my $value = $self->{$_};
91              
92 15 100 66     65 if (blessed $value && $value->can('to_hash')) {
93 1         4 $_ => $value->compact;
94             }
95             else {
96 14         72 $_ => $value;
97             }
98 11         25 } grep { $_ ne '__HASH_COMPACT_OPTIONS__' } CORE::keys %$self
99             }
100             }
101              
102             sub original {
103 1     1 1 4 my $self = shift;
104 1         3 +{ map { $_ => $self->param($_) } $self->keys }
  3         6  
105             }
106              
107             !!1;
108              
109             __END__