File Coverage

blib/lib/Data/YAML/Writer.pm
Criterion Covered Total %
statement 61 65 93.8
branch 18 24 75.0
condition 6 10 60.0
subroutine 12 13 92.3
pod 2 2 100.0
total 99 114 86.8


line stmt bran cond sub pod time code
1             package Data::YAML::Writer;
2              
3 4     4   49556 use strict;
  4         11  
  4         162  
4 4     4   22 use warnings;
  4         8  
  4         124  
5 4     4   25 use Carp;
  4         16  
  4         302  
6              
7 4     4   21 use vars qw{$VERSION};
  4         7  
  4         3708  
8              
9             $VERSION = '0.0.6';
10              
11             my $ESCAPE_CHAR = qr{ [\x00-\x1f\"] }x;
12              
13             my @UNPRINTABLE = qw(
14             z x01 x02 x03 x04 x05 x06 a
15             x08 t n v f r x0e x0f
16             x10 x11 x12 x13 x14 x15 x16 x17
17             x18 x19 x1a e x1c x1d x1e x1f
18             );
19              
20             # Create an empty Data::YAML::Writer object
21             sub new {
22 15     15 1 10540 my $class = shift;
23 15         128 bless {}, $class;
24             }
25              
26             sub write {
27 15     15 1 28 my $self = shift;
28              
29 15 50       51 croak "Need something to write"
30             unless @_;
31              
32 15         35 my $obj = shift;
33 15   50     102 my $out = shift || \*STDOUT;
34              
35 15 50       70 croak "Need a reference to something I can write to"
36             unless ref $out;
37              
38 15         55 $self->{writer} = $self->_make_writer( $out );
39              
40 15         46 $self->_write_obj( '---', $obj );
41 15         202 $self->_put( '...' );
42              
43 15         187 delete $self->{writer};
44             }
45              
46             sub _make_writer {
47 15     15   24 my $self = shift;
48 15         18 my $out = shift;
49              
50 15         32 my $ref = ref $out;
51              
52 15 100 0     43 if ( 'CODE' eq $ref ) {
    100          
    50          
    0          
53 13         44 return $out;
54             }
55             elsif ( 'ARRAY' eq $ref ) {
56 1     26   6 return sub { push @$out, shift };
  26         87  
57             }
58             elsif ( 'SCALAR' eq $ref ) {
59 1     26   5 return sub { $$out .= shift() . "\n" };
  26         95  
60             }
61             elsif ( 'GLOB' eq $ref || 'IO::Handle' eq $ref ) {
62 0     0   0 return sub { print $out shift(), "\n" };
  0         0  
63             }
64              
65 0         0 croak "Can't write to $out";
66             }
67              
68             sub _put {
69 150     150   233 my $self = shift;
70 150         572 $self->{writer}->( join '', @_ );
71             }
72              
73             sub _enc_scalar {
74 202     202   235 my $self = shift;
75 202         211 my $val = shift;
76              
77 202 100       466 return '~' unless defined $val;
78              
79 199 100       781 if ( $val =~ /$ESCAPE_CHAR/ ) {
80 10         23 $val =~ s/\\/\\\\/g;
81 10         15 $val =~ s/"/\\"/g;
82 10         49 $val =~ s/ ( [\x00-\x1f] ) / '\\' . $UNPRINTABLE[ ord($1) ] /gex;
  16         61  
83 10         105 return qq{"$val"};
84             }
85              
86 189 100 100     835 if ( length( $val ) == 0 or $val =~ /\s/ ) {
87 11         20 $val =~ s/'/''/;
88 11         43 return "'$val'";
89             }
90              
91 178         609 return $val;
92             }
93              
94             sub _write_obj {
95 135     135   171 my $self = shift;
96 135         231 my $prefix = shift;
97 135         224 my $obj = shift;
98 135   100     312 my $indent = shift || 0;
99              
100 135 100       263 if ( my $ref = ref $obj ) {
101 34         66 my $pad = ' ' x $indent;
102 34         77 $self->_put( $prefix );
103 34 100       221 if ( 'HASH' eq $ref ) {
    50          
104 26         134 for my $key ( sort keys %$obj ) {
105 101         449 my $value = $obj->{$key};
106 101         212 $self->_write_obj( $pad . $self->_enc_scalar( $key ) . ':',
107             $value, $indent + 1 );
108             }
109             }
110             elsif ( 'ARRAY' eq $ref ) {
111 8         20 for my $value ( @$obj ) {
112 19         178 $self->_write_obj( $pad . '-', $value, $indent + 1 );
113             }
114             }
115             else {
116 0         0 croak "Don't know how to encode $ref";
117             }
118             }
119             else {
120 101         288 $self->_put( $prefix, ' ', $self->_enc_scalar( $obj ) );
121             }
122             }
123              
124             1;
125              
126             __END__
127              
128              
129             =head1 NAME
130              
131             Data::YAML::Writer - Easy YAML serialisation
132              
133             =head1 VERSION
134              
135             This document describes Data::YAML::Writer version 0.0.6
136              
137             =head1 SYNOPSIS
138            
139             use Data::YAML::Writer;
140            
141             my $data = {
142             one => 1,
143             two => 2,
144             three => [ 1, 2, 3 ],
145             };
146            
147             my $yw = Data::YAML::Writer->new;
148            
149             # Write to an array...
150             $yw->write( $data, \@some_array );
151            
152             # ...an open file handle...
153             $yw->write( $data, $some_file_handle );
154            
155             # ...a string ...
156             $yw->write( $data, \$some_string );
157            
158             # ...or a closure
159             $yw->write( $data, sub {
160             my $line = shift;
161             print "$line\n";
162             } );
163              
164              
165             =head1 DESCRIPTION
166              
167             Encodes a scalar, hash reference or array reference as YAML.
168              
169             In the spirit of L<YAML::Tiny> this is a lightweight, dependency-free
170             YAML writer. While C<YAML::Tiny> is designed principally for working
171             with configuration files C<Data::YAML> concentrates on the transparent
172             round-tripping of YAML serialized Perl data structures.
173              
174             The syntax produced by C<Data::YAML::Writer> is a subset of YAML.
175             Specifically it is the same subset of YAML that L<Data::YAML::Reader>
176             consumes. See L<Data::YAML> for more information.
177              
178             =head1 INTERFACE
179              
180             =over
181              
182             =item C<< new >>
183              
184             The constructor C<new> creates and returns an empty C<Data::YAML::Writer> object.
185              
186             =item C<< write( $obj, $output ) >>
187              
188             Encode a scalar, hash reference or array reference as YAML.
189              
190             my $writer = sub {
191             my $line = shift;
192             print SOMEFILE "$line\n";
193             };
194            
195             my $data = {
196             one => 1,
197             two => 2,
198             three => [ 1, 2, 3 ],
199             };
200            
201             my $yw = Data::YAML::Writer->new;
202             $yw->write( $data, $writer );
203              
204              
205             The C< $output > argument may be
206              
207             =over
208              
209             =item * a reference to a scalar to append YAML to
210              
211             =item * the handle of an open file
212              
213             =item * a reference to an array into which YAML will be pushed
214              
215             =item * a code reference
216              
217             =back
218              
219             If you supply a code reference the subroutine will be called once for
220             each line of output with the line as its only argument. Passed lines
221             will have no trailing newline.
222              
223             =back
224              
225             =head1 BUGS AND LIMITATIONS
226              
227             No bugs have been reported.
228              
229             Please report any bugs or feature requests to
230             C<data-yaml@rt.cpan.org>, or through the web interface at
231             L<http://rt.cpan.org>.
232              
233             =head1 SEE ALSO
234              
235             L<YAML::Tiny>, L<YAML>, L<YAML::Syck>, L<Config::Tiny>, L<CSS::Tiny>
236              
237             =head1 AUTHOR
238              
239             Andy Armstrong C<< <andy@hexten.net> >>
240              
241             =head1 LICENCE AND COPYRIGHT
242              
243             Copyright (c) 2007, Andy Armstrong C<< <andy@hexten.net> >>. All rights reserved.
244              
245             This module is free software; you can redistribute it and/or
246             modify it under the same terms as Perl itself. See L<perlartistic>.
247              
248             =head1 DISCLAIMER OF WARRANTY
249              
250             BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
251             FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
252             OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
253             PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
254             EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
255             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
256             ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
257             YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
258             NECESSARY SERVICING, REPAIR, OR CORRECTION.
259              
260             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
261             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
262             REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
263             LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
264             OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
265             THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
266             RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
267             FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
268             SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
269             SUCH DAMAGES.