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