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