File Coverage

blib/lib/Tie/Hash/Attribute.pm
Criterion Covered Total %
statement 62 64 96.8
branch 22 28 78.5
condition n/a
subroutine 16 17 94.1
pod n/a
total 100 109 91.7


line stmt bran cond sub pod time code
1             package Tie::Hash::Attribute;
2 3     3   49184 use 5.006;
  3         12  
3 3     3   17 use strict;
  3         8  
  3         79  
4 3     3   23 use warnings FATAL => 'all';
  3         7  
  3         2822  
5             our $VERSION = '1.03';
6             our @ISA = 'Tie::Hash';
7              
8             our $ATTR_SORT = 0;
9              
10 17     17   1936 sub STORE { $_[0]{$_[1]}=$_[2] }
11 5     5   1292 sub SCALAR { _mk_str($_[0]) }
12 3     3   76 sub EXISTS { exists $_[0]{$_[1]} }
13 1     1   358 sub FIRSTKEY { each %{$_[0]} }
  1         7  
14 3     3   6 sub NEXTKEY { each %{$_[0]} }
  3         10  
15 0     0   0 sub DELETE { delete $_[0]{$_[1]} }
16 4     4   780 sub CLEAR { %{$_[0]} = () }
  4         33  
17              
18             sub TIEHASH {
19 2     2   29 my $class = shift;
20 2         7 my %args = @_;
21 2 50       13 $ATTR_SORT = 1 if defined $args{sorted};
22 2         10 return bless {}, $class;
23             }
24              
25             sub FETCH {
26 37     37   3251 my $self = shift;
27 37         55 my $arg = shift;
28 37 100       173 return $self->{$arg} unless substr($arg,0,1) eq '-';
29 17         65 $arg =~ s/^-//;
30 17         52 return _mk_str( $self->{$arg} );
31             }
32              
33             sub _mk_str {
34 22     22   37 my $hash = shift;
35 22         36 my $str = '';
36 22         32 my %seen;
37 22 50       109 my @keys = $ATTR_SORT ? sort keys %$hash : keys %$hash;
38 22         51 for my $key (@keys) {
39 31 100       107 next if $seen{lc$key}++;
40 27         52 my $val = $hash->{$key};
41 27 100       87 $val = _stringify( $val ) if ref $val eq 'HASH';
42 27 50       67 $val = _rotate( $val ) if ref $val eq 'ARRAY';
43 27 100       838 next unless defined $val;
44 26         57 $str .= sprintf ' %s="%s"', _key( $key ), _val( $val );
45             }
46 22         134 return $str;
47             }
48              
49             sub _key {
50 26     26   38 my $key = shift;
51 26 50       57 return '' unless defined $key;
52 26         50 $key =~ s/\s//g;
53 26         47 $key =~ s/["'>=\/]//g;
54 26         69 return $key;
55             }
56              
57             sub _val {
58 26     26   41 my $val = shift;
59 26 100       95 $val = '' if $val =~ /^\s+$/;
60 26         45 $val =~ s/"//g;
61 26         146 return $val;
62             }
63              
64             sub _rotate {
65 10     10   15 my $ref = shift;
66 10         16 my $next = shift @$ref;
67 10         19 push @$ref, $next;
68 10         21 return $next;
69             }
70              
71             sub _stringify {
72 16     16   25 my $hash = shift;
73              
74 16 50       67 my @keys = $ATTR_SORT ? sort keys %$hash : keys %$hash;
75 16         34 my @vals = map { my $val;
  25         33  
76              
77 25 100       87 if (ref $hash->{$_} eq 'ARRAY') {
    100          
78 10         21 $val = _rotate( $hash->{$_} );
79             } elsif (ref $hash->{$_} eq 'HASH') {
80 11 50       27 ($val) = $ATTR_SORT ? sort keys %{ $hash->{$_} } : keys %{ $hash->{$_} };
  11         37  
  0         0  
81             } else {
82 4         6 $val = $hash->{$_};
83             }
84              
85 25         92 join( ': ', $_, $val);
86              
87             } @keys;
88              
89 16 100       101 return join( '; ', @vals ) . (@vals > 1 ? ';' : '');
90             }
91              
92             1;
93              
94             __END__