File Coverage

blib/lib/XML/Spew.pm
Criterion Covered Total %
statement 12 72 16.6
branch 0 14 0.0
condition 0 3 0.0
subroutine 4 13 30.7
pod n/a
total 16 102 15.6


line stmt bran cond sub pod time code
1             package XML::Spew;
2              
3 1     1   55731 use warnings;
  1         2  
  1         31  
4 1     1   5 use strict;
  1         2  
  1         102  
5              
6             our $VERSION = '0.02';
7              
8 1     1   6 use Carp;
  1         7  
  1         175  
9              
10             sub _new {
11 0     0     my $class = shift;
12              
13 0   0       return bless { stack => [ ] }, ref( $class ) || $class;
14             }
15              
16             sub _tags {
17 0     0     my $class = shift;
18              
19 0 0         croak "_tags must be passed at least one argument" unless @_;
20 0           my @tags = @_;
21              
22 0           foreach my $tag( @tags ) {
23             # install methods
24             {
25 1     1   5 no strict 'refs';
  1         3  
  1         698  
  0            
26 0           *{ $class . '::' . $tag } = $class->__m_meth( $tag );
  0            
27 0           *{ $class . '::start_' . $tag } = $class->__s_meth( $tag );
  0            
28 0           *{ $class . '::end_' . $tag } = $class->__e_meth( $tag );
  0            
29             }
30             }
31             }
32              
33             # returns a coderef for the main tag method
34             sub __m_meth {
35 0     0     my $class = shift;
36 0           my $tag = shift;
37              
38             return sub {
39 0     0     my $self = shift;
40 0           my $r = '<' . $tag;
41            
42             # check for attributes
43 0 0         if( ref( $_[0] ) eq 'HASH' ) {
44 0           $r .= $self->__attributes( shift );
45             }
46            
47             # check if we have an arrayref to distribute over
48 0 0         if( ref( $_[0] ) eq 'ARRAY' ) {
49 0           $r .= '>';
50 0           my $e = '';
51 0           return map { $r . $_ . $e } @{ $_[0] };
  0            
  0            
52             }
53              
54             # check if we have child data
55 0 0         if( @_ ) {
56 0           $r .= '>' . join '', @_;
57 0           $r .= '';
58             } else {
59 0           $r .= ' />';
60             }
61            
62 0           return $r;
63 0           };
64             }
65              
66             # returns a coderef for the start tag method
67             sub __s_meth {
68 0     0     my $class = shift;
69 0           my $tag = shift;
70              
71             return sub {
72 0     0     my $self = shift;
73 0           my $r = '<' . $tag;
74              
75             # push this tag onto the tag stack
76 0           push @{ $self->{stack} }, $tag;
  0            
77              
78             # check for attributes
79 0 0         if( ref( $_[0] ) eq 'HASH' ) {
80 0           $r .= $self->__attributes( shift );
81             }
82              
83             # check for erroneous data
84 0 0         if( @_ ) {
85 0           carp "Ignoring extra arguments to start_$tag(). You might want $tag().";
86             }
87              
88 0           $r .= '>';
89              
90 0           return $r;
91 0           };
92             }
93              
94             # returns a coderef for the end tag method
95             sub __e_meth {
96 0     0     my $class = shift;
97 0           my $tag = shift;
98              
99             return sub {
100 0     0     my $self = shift;
101            
102             # fatal error if this tag is not on top of the stack
103 0           my $top = $self->{stack}[-1];
104 0 0         unless( $top eq $tag ) {
105 0           croak "Invalid nesting: can not close <$tag> while <$top> still open";
106             }
107              
108             # pop this tag off the stack and close it
109 0           pop @{ $self->{stack} };
  0            
110              
111 0           return '';
112 0           };
113             }
114              
115              
116             sub __attributes {
117 0     0     my $self = shift;
118 0           my $attr_ref = shift;
119              
120 0           my $r;
121 0           while( my( $k, $v ) = each %$attr_ref ) {
122 0           $r .= " $k=\"$v\"";
123             }
124              
125 0           return $r;
126             }
127              
128             1;
129              
130             __END__