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