File Coverage

blib/lib/IO/YAML.pm
Criterion Covered Total %
statement 196 258 75.9
branch 68 114 59.6
condition 19 47 40.4
subroutine 44 59 74.5
pod 14 28 50.0
total 341 506 67.3


line stmt bran cond sub pod time code
1             package IO::YAML;
2              
3 9     9   7929 use strict;
  9         17  
  9         286  
4 9     9   39 use warnings;
  9         10  
  9         275  
5              
6 9     9   4939 use IO::File;
  9         63857  
  9         1126  
7 9     9   58 use Errno;
  9         13  
  9         378  
8 9     9   38 use Fcntl qw(:seek);
  9         15  
  9         1228  
9 9     9   42 use Symbol;
  9         14  
  9         459  
10              
11 9     9   38 use vars qw($VERSION $AUTOLOAD);
  9         19  
  9         19192  
12              
13             $VERSION = '0.10';
14              
15             my ($yaml_loader, $yaml_dumper);
16              
17             sub new {
18 12     12 1 82993 my ($cls, @args) = @_;
19 12         19 my %args;
20 12 100       56 ($yaml_loader, $yaml_dumper) = find_yaml_code() if !defined $yaml_loader;
21 12 100 33     116 if (UNIVERSAL::isa($args[0], 'GLOB')) {
    50 33        
22             # IO::YAML->new($fh)
23             # IO::YAML->new($fh, $mode, %opt_args)
24             # IO::YAML->new($fh, %args)
25 4         9 $args{'handle'} = shift @args;
26 4 100 66     35 $args{'mode'} = shift @args
27             if scalar(@args) % 2
28             && $args[0] =~ /^\+?[<>rwa]|>>|\d+$/;
29             }
30             elsif (scalar(@args) >= 2
31             && $args[1] =~ /^\+?[<>rwa]|>>|\d+$/
32             && $args[0] ne 'mode') {
33             # IO::YAML->new($path, $mode)
34             # IO::YAML->new($path, $mode, %args)
35 0         0 $args{'mode'} = splice(@args, 1, 1);
36             }
37 12 100       39 if (scalar(@args) % 2) {
38             # --- Odd number of args
39 3 50 33     11 if (ref($args[0]) eq ''
40             or UNIVERSAL::can($args[0], 'stringify')) {
41 3         4 unshift @args, 'path';
42             }
43             else {
44 0         0 die "Odd argument can't be interpreted";
45             }
46             }
47             %args = (
48 12         63 %args,
49             'auto_load' => 0,
50             'auto_terminate' => 0,
51             @args,
52             'buffer' => [],
53             );
54 12         44 my $self = bless Symbol::gensym(), $cls;
55 12         167 foreach (keys %args) {
56 46         94 *$self->{$_} = $args{$_};
57             }
58 12         35 return $self->init;
59             }
60              
61 21 100   21 1 41 sub path { scalar @_ > 1 ? *{$_[0]}->{'path'} = $_[1] : *{$_[0]}->{'path'} }
  9         17  
  12         20  
62 33 100   33 1 67 sub mode { scalar @_ > 1 ? *{$_[0]}->{'mode'} = $_[1] : *{$_[0]}->{'mode'} }
  22         40  
  11         34  
63 32 100   32 1 53 sub auto_load { scalar @_ > 1 ? *{$_[0]}->{'auto_load'} = $_[1] : *{$_[0]}->{'auto_load'} }
  5         11  
  27         470  
64 9 100   9 1 416 sub auto_terminate { scalar @_ > 1 ? *{$_[0]}->{'auto_terminate'} = $_[1] : *{$_[0]}->{'auto_terminate'} }
  1         4  
  8         31  
65              
66 21 50   21 0 59 sub auto_close { scalar @_ > 1 ? *{$_[0]}->{'auto_close'} = $_[1] : *{$_[0]}->{'auto_close'} }
  21         41  
  0         0  
67 30 50   30 0 40 sub buffer { scalar @_ > 1 ? *{$_[0]}->{'buffer'} = $_[1] : *{$_[0]}->{'buffer'} }
  0         0  
  30         39  
68 125 100   125 0 210 sub handle { scalar @_ > 1 ? *{$_[0]}->{'handle'} = $_[1] : *{$_[0]}->{'handle'} }
  22         42  
  103         616  
69              
70             sub terminate {
71 1     1 0 3 my ($self) = @_;
72 1         5 my $fh = $self->handle;
73 1 50       3 die "Can't terminate a document in an unopened stream"
74             unless defined $fh;
75 1         2 my $mode = $self->mode;
76 1 50       3 die "Can't terminate a document in a stream opened for read-only access"
77             if $mode =~ /^[r<]$/;
78 1 50       3 print $fh "...\n" or die "Couldn't terminate document: $!";
79 1         1 return $fh;
80             }
81              
82             sub open {
83 9     9 1 2026 my ($self, $path, $mode) = @_;
84            
85 9         21 my $fh = $self->handle;
86 9 50 33     59 if (defined $path and defined $fh) {
87             # --- Reopen a different file
88 0         0 $self->close;
89 0         0 undef $fh;
90             }
91            
92 9 50       24 if (defined $fh) {
93             # Default is to read it
94 0 0       0 $mode = '<' unless defined $mode;
95             }
96             else {
97            
98 9   33     19 $path ||= $self->path;
99            
100 9 50       19 unless (defined $path) {
101             # $! = "No such file or directory";
102 0 0       0 if (exists &Errno::ENOENT) {
103 0         0 $! = &Errno::ENOENT;
104             }
105             else {
106 0         0 CORE::open(gensym, undef);
107             }
108 0         0 return;
109             }
110            
111 9         48 $fh = IO::File->new;
112 9         247 $self->handle($fh);
113            
114 9   66     33 ($path, $mode) = $self->normalize_path_and_mode($path, $mode || $self->mode);
115 9         19 $self->path($path);
116 9         19 $self->mode($mode);
117            
118 9 50       29 unless ($fh->open($path, $mode)) {
119 0         0 $self->handle(undef);
120             #unlink $path
121             # if -e $path and $mode eq '>';
122 0         0 return;
123             }
124            
125 9         718 $self->auto_close(1);
126            
127             }
128            
129 9         20 $! = 0;
130 9         27 return $fh;
131            
132             }
133              
134             sub close {
135 13     13 1 662 my ($self) = @_;
136             # return unless $self->auto_close;
137 13         32 my $fh = $self->handle;
138 13 50       40 if (defined $fh) {
139 13         43 fh_close($fh);
140 13         46 $self->handle(undef);
141             }
142 13         35 $self->mode(undef);
143 13         46 undef *$self->{$_} for qw(mode);
144 13         48 return $self;
145             }
146              
147             sub print {
148 7     7 1 339 my $self = shift;
149 7   50     19 my $fh = $self->handle || $self->open || die "Can't open: $!";
150 7 100       34 my @terminator = $self->auto_terminate ? ("...\n") : ();
151             print $fh ($yaml_dumper->($_), @terminator) or die $!
152 7   50     617 foreach @_;
153 7         77 return 1;
154             }
155              
156             sub getline {
157 27     27 1 33 my ($self) = @_;
158 27   50     37 my $fh = $self->handle || $self->open || die "Can't open: $!";
159 27         57 my $buffer = $self->buffer;
160 27         22 my $source;
161 27         22 while (1) {
162 31 100       97 $source = scalar @$buffer ? shift @$buffer : <$fh>;
163 31 50       146 return unless defined $source;
164 31 100       69 last unless $source =~ /^#/;
165             }
166 27         70 while (defined(my $line = <$fh>)) {
167 71 100       370 if ($line =~ /^\.\.\.$/) {
    100          
168             # End of stream
169 3         6 last;
170             }
171             elsif ($line =~ /^---/) {
172             # Oops -- hit start of next document in stream
173 22         30 push @$buffer, $line;
174 22         19 last;
175             }
176 46         124 $source .= $line;
177             }
178 27 100       40 my $retval = $self->auto_load ? $yaml_loader->($source) : $source;
179 27         75 return $retval;
180             }
181              
182             sub getlines {
183 2     2 1 3 my ($self) = @_;
184 2   50     4 my $fh = $self->handle || $self->open || die "Can't open: $!";
185 2         41 my @lines = <$fh>;
186 2         171 return $yaml_loader->(join('', @lines));
187             }
188              
189             sub next {
190 0 0   0 0 0 goto &getlines if wantarray;
191 0         0 goto &getline;
192             }
193              
194             sub seek {
195 3     3 1 2355 my ($self, $pos, $whence) = @_;
196 3   50     7 my $fh = $self->handle || $self->open || die "Can't open: $!";
197 3   50     6 my $result = fh_seek($fh, $pos, $whence)
198             || die "Couldn't seek: $!";
199 3         7 my $old_pos = fh_tell($fh);
200 3         10 my $buffer = $self->buffer;
201 3         4 my $source;
202 3 50       5 if ($pos) {
203             # Arbitrary seek -- make sure we're at the beginning of a YAML document
204 0 0       0 $result = fh_seek($fh, $pos, $whence)
205             or die "Couldn't seek: $!";
206 0         0 $source = <$fh>;
207 0 0       0 if (!defined($source)) {
    0          
208             # We're at the end of the stream -- that's fine, just
209             # set the buffer to the empty string
210 0         0 @$buffer = ();
211             }
212             elsif ($source !~ /^---(?=\s)/) {
213             # Oops! We were expecting the '---' (etc.) line that
214             # begins a YAML document, but we found something else.
215             # Try to put things back the way they were, then die.
216 0         0 fh_seek($fh, $old_pos, SEEK_SET);
217 0         0 die "Seek not allowed except to start of YAML document";
218             }
219             }
220             else {
221             # Clear the buffer
222 3         6 @$buffer = ();
223             }
224 3         15 return $result;
225             }
226              
227             sub tell {
228 0     0 1 0 my ($self) = @_;
229 0   0     0 my $fh = $self->handle || $self->open || die "Can't open: $!";
230 0         0 my $pos = fh_tell($fh);
231 0 0       0 die "Can't get file cursor position: $!"
232             unless $! eq '';
233 0         0 return $pos;
234             }
235              
236             sub truncate {
237 0     0 1 0 my ($self, $length) = @_;
238 0 0 0     0 die "Arbitrary truncates not allowed"
239             unless $length == 0
240             or $length == $self->tell;
241 0   0     0 my $fh = $self->handle || $self->open || die "Can't open: $!";
242 0         0 fh_truncate($fh, $length);
243 0         0 return $! ne '';
244             }
245              
246             sub eof {
247 3     3 1 10 my ($self) = @_;
248 3   50     4 my $fh = $self->handle || $self->open || die "Can't open: $!";
249 3         5 return fh_eof($fh);
250             }
251              
252             sub UNTIE {
253 12     12   20 my ($self, $count) = @_;
254 12 50       36 $self->close if $self->handle;
255             }
256              
257             sub DESTROY {
258 12     12   8841 my ($self) = @_;
259 12 100       47 $self->close if $self->handle;
260 12 50 33     308 unless ( $^V and $^V lt '5.8.0' ) {
261 12 50       64 untie *$self if tied *$self;
262             }
263             }
264              
265             sub AUTOLOAD {
266 0     0   0 my $self = shift;
267 0         0 my $fh = $self->handle;
268 0         0 (my $method = $AUTOLOAD) =~ s/.*:://;
269 0         0 my $f = UNIVERSAL::can($fh, $method);
270 0 0       0 die "Unknown method '$method' called"
271             unless defined $f;
272 0         0 unshift @_, $fh;
273 0         0 goto &$f;
274             }
275              
276             # --- Private methods
277              
278             sub normalize_path_and_mode {
279 9     9 0 14 my ($self, $path, $mode) = @_;
280 9 50       33 if ($path =~ s/^(<|>|>>|\+<|\+>)\s*//) {
281 0         0 $mode = $1;
282             }
283 9 100       29 return ($path, '<') unless defined $mode;
284 5         41 my %mode_norm = qw(
285             < <
286             r <
287             > >
288             w >
289             >> >>
290             a >>
291             +< +<
292             r+ +<
293             +> +>
294             w+ +>
295             );
296 5 50       14 $mode = $mode_norm{$mode}
297             or die "Unknown mode: '$mode'";
298 5         26 return ($path, $mode);
299             }
300              
301             sub init {
302 12     12 0 17 my ($self) = @_;
303 12         29 $self->auto_close(0);
304 12         24 my $path = $self->path;
305 12         27 my $fh = $self->handle;
306 12 100       39 if ($fh) {
    100          
307             # --- Nothing to do
308             }
309             elsif (defined $path) {
310 3         5 $self->open($path, $self->mode);
311             }
312             else {
313             # --- Nothing to do
314             }
315 12         36 $self->tie; # unless $self->dont_tie;
316 12         47 return $self;
317             }
318              
319             # --- Tie interface
320              
321             sub tie {
322 12     12 0 16 my ($self) = @_;
323 12         67 tie *$self, $self;
324 12         21 return $self;
325             }
326              
327             sub TIEHANDLE() {
328 12 50   12   57 return $_[0] if ref $_[0];
329 0         0 my $class = shift;
330 0         0 my $self = bless Symbol::gensym(), $class;
331 0         0 $self->init(@_);
332             }
333              
334             sub READLINE() {
335 28 100   28   11061 goto &getlines if wantarray;
336 27         63 goto &getline;
337             }
338              
339             sub BINMODE {
340 0     0   0 binmode shift()->handle;
341             }
342              
343             sub GETC {
344 0     0   0 die "Arbitrary GETCs not allowed";
345             }
346              
347             sub PRINT {
348 9     9   53 no warnings;
  9         14  
  9         623  
349 4     4   1189 shift()->print(@_);
350             }
351              
352             sub PRINTF {
353 9     9   37 no warnings;
  9         15  
  9         1299  
354 0     0   0 shift()->print(sprintf(@_));
355             }
356              
357             sub READ {
358 0     0   0 die "Arbitrary reads not allowed";
359             }
360              
361             sub WRITE {
362 0     0   0 die "Arbitrary writes not allowed";
363             }
364              
365             sub SEEK {
366 0     0   0 shift()->seek(@_);
367             }
368              
369             sub TELL {
370 0     0   0 shift()->tell;
371             }
372              
373             sub EOF {
374 0     0   0 shift()->eof;
375             }
376              
377             sub CLOSE {
378 0     0   0 shift()->close;
379             }
380              
381             sub FILENO {
382 9     9   41 no warnings;
  9         10  
  9         585  
383 0     0   0 fileno shift()->handle;
384             }
385              
386              
387              
388              
389             # --- Functions
390              
391             sub fh_close {
392 13     13 0 15 my ($fh) = @_;
393 13 50       45 if (UNIVERSAL::isa($fh, 'GLOB')) {
394 9     9   34 no warnings;
  9         11  
  9         649  
395 13         25 $! = 0;
396 13         265 close $fh;
397             }
398             else {
399 0         0 $fh->close;
400             }
401             }
402              
403             sub fh_seek {
404 3     3 0 4 my ($fh, $pos, $whence) = @_;
405 3 50       14 if (UNIVERSAL::isa($fh, 'GLOB')) {
406 9     9   33 no warnings;
  9         10  
  9         689  
407 3         7 $! = 0;
408 3         25 seek $fh, $pos, $whence;
409             }
410             else {
411 0         0 $fh->seek(@_);
412             }
413             }
414              
415             sub fh_tell {
416 3     3 0 5 my ($fh) = @_;
417 3 50       10 if (UNIVERSAL::isa($fh, 'GLOB')) {
418 9     9   38 no warnings;
  9         14  
  9         627  
419 3         5 $! = 0;
420 3         6 tell $fh;
421             }
422             else {
423 0         0 $fh->tell;
424             }
425             }
426              
427             sub fh_truncate {
428 0     0 0 0 my ($fh, $length) = @_;
429 0 0       0 if (UNIVERSAL::isa($fh, 'GLOB')) {
430 9     9   30 no warnings;
  9         9  
  9         612  
431 0         0 $! = 0;
432 0         0 truncate $fh, $length;
433             }
434             else {
435 0         0 $fh->truncate($length);
436             }
437             }
438              
439             sub fh_eof {
440 3     3 0 2 my ($fh) = @_;
441 3 50       7 if (UNIVERSAL::isa($fh, 'GLOB')) {
442 9     9   34 no warnings;
  9         8  
  9         1884  
443 3         4 $! = 0;
444 3         27 eof $fh;
445             }
446             else {
447 0         0 $fh->eof;
448             }
449             }
450              
451             sub find_yaml_code {
452 9     9 0 23 my @yaml_packages = qw(
453             YAML::Any
454             YAML::XS
455             YAML::Syck
456             YAML::Old
457             YAML
458             YAML::Tiny
459             );
460 9         21 for my $pkg (@yaml_packages) {
461 18         70 (my $path = $pkg) =~ s/::/\//g;
462 18         32 $path .= '.pm';
463 18 100 100     780 eval "require $pkg; 1" or next if !$INC{$path};
464 9 50       117 my $L = $pkg->can('Load') or next;
465 9 50       139 my $D = $pkg->can('Dump') or next;
466 9         37 return ($L, $D);
467             }
468 0           die "Couldn't find a suitable YAML package";
469             }
470              
471             1;
472              
473              
474             =head1 NAME
475              
476             IO::YAML - read and write YAML streams incrementally
477              
478             =head1 SYNOPSIS
479              
480             use IO::YAML;
481            
482             $io = IO::YAML->new($path_or_filehandle);
483             $io = IO::YAML->new(
484             'path' => '/path/to/a/file',
485             'auto_load' => $bool,
486             );
487             $io = IO::YAML->new(
488             'handle' => $fh,
489             'mode' => '>', # or 'w'; '<' or 'r'; '>>' or 'a'
490             );
491            
492             $io = IO::YAML->new;
493             $io->open($path, '>') or die $!; # Open a stream for writing
494             $io->open($path, '>>') or die $!; # Open a stream for appending
495            
496             # Automatically add "...\n" at end of each document written
497             $io->auto_terminate(1);
498            
499             print $io $mystring;
500             print $io @myvalues;
501             print $io \@myarray;
502             print $io \%myhash;
503             print $io $myobj;
504            
505             $io = IO::YAML->new;
506             $io->open($path, '<') or die $!; # Open a stream for reading
507             while (<$io>) {
508             $data = YAML::Load($_);
509             }
510            
511             $io = IO::YAML->new;
512             $io->open($path) or die $!; # Default mode is reading
513             $io->auto_load(1);
514             while (not $io->eof) {
515             $data = <$io>;
516             }
517            
518             $io = IO::YAML->new($path_or_handle);
519             $io->auto_load(1);
520             my @values = <$io>; # Roughly equivalent to YAML::LoadFile(...)
521              
522             =head1 DESCRIPTION
523              
524             B may be used to read and write YAML streams one C (i.e.,
525             one value) at a time.
526              
527             A YAML stream is a file consisting of a sequence of YAML documents, each of
528             which may (optionally) be terminated by a line consisting solely of three
529             periods (C<...>).
530              
531             The first line of each document must begin with the three-byte sequence C<--->.
532              
533             Here's a simple YAML file consisting of three documents; their values are the
534             string 'foo', an empty array, and a hash with three elements:
535              
536             --- #YAML:1.0 foo
537             --- #YAML:1.0 []
538             --- #YAML:1.0
539             title: Testing 1, 2, 3
540             author: nkuitse
541             date: 2004-03-05
542             ^D
543              
544             (Here, C<^D> indicates the end of the file.)
545              
546             In this next example, the stream consists of a single YAML document whose value
547             is C:
548              
549             --- ~
550             ^D
551              
552             As this example shows, the first line in each document need not contain the
553             full YAML 1.0 header.
554              
555             =head2 Reading from a YAML stream
556              
557             To read from a YAML stream, you may use the angle-brackets operator (e.g.,
558             E$fhE) or the equivalent methods C or C. Rather than
559             reading a single line, this will read an entire YAML document.
560              
561             while(defined(my $yaml = <$io>)) {
562             my $value = YAML::Load($yaml);
563             ...
564             }
565              
566             The C step may be omitted by setting the IO::YAML object's
567             C property to a true value:
568              
569             $io->auto_load(1);
570             while(defined(my $value = <$io>)) {
571             ...
572             }
573              
574             However, this example is complicated by the fact that the value of a YAML
575             document may be undef; the loop as written will terminate when the end of the
576             stream is reached I when an undef value is read.
577              
578             To avoid this problem while still taking advantage of the C property,
579             use C<< $io->eof >> to test for the end of the stream:
580              
581             $io->auto_load(1);
582             while(not $io->eof) {
583             my $value = <$io>;
584             ...
585             }
586              
587             L properly recognizes the document terminator (C<...>).
588             Some versions of L do B recognize it, however; in order to
589             prevent problems when reading YAML streams with auto-loading off,
590             L strips the document terminator line if it is present.
591              
592             =head2 Writing to a YAML stream
593              
594             To print to a YAML stream, call C just as you would with a regular file
595             handle; the value(s) you're printing will be converted to YAML format before
596             being written:
597              
598             $io = IO::YAML->new;
599             $io->open('>file') or die "Couldn't open 'file'";
600             print $io $anything;
601              
602             You can `print' anything that YAML is capable of serializing; an exception will
603             be raised if you attempt to print something that can't be serialized (e.g., a
604             reference to a subroutine).
605              
606             The complication with undef values that affects the reading of a YAML stream
607             is not an issue when writing to a YAML stream.
608              
609             =head2 Terminating YAML documents
610              
611             Documents in a YAML stream may be terminated by a line consisting solely of
612             the string "...". You can use the C method to add an explicit
613             document terminator to a YAML stream that you have open for writing (or
614             appending):
615              
616             $io = IO::YAML->new($file_or_handle, '>');
617            
618             foreach my $value (@data_values) {
619             print $io $value;
620             $io->terminate;
621             }
622              
623             It's generally safer to have YAML documents terminated automatically:
624              
625             # 1. Set auto_terminate to a true value
626             # a) When creating the object
627             $io = IO::YAML->new(
628             'handle' => $fh,
629             'mode' => '>>',
630             'auto_terminate' => 1,
631             );
632             # or b) At any point thereafter
633             $io = IO::YAML->new(...);
634             $io->auto_terminate(1);
635            
636             # 2. Documents are now auto-terminated
637             foreach my $value (@data_values) {
638             print $io $value;
639             # $io->terminate called implicitly
640             }
641              
642             Note that it's not the YAML I that's terminated; it's the YAML document
643             that was previously written.
644              
645             =head2 Low-level access
646              
647             Sometimes it is helpful to be able to access a YAML stream at a lower level.
648             For example, you may wish to read and write a file consisting of a YAML
649             document (here, serving as a header of sorts) followed by arbitrary text.
650             The C method may be used to obtain the underlying file handle so
651             that it can be used for this low-level access:
652              
653             # Read header + body
654             $io->auto_load(1);
655             $header = <$io>;
656             $fh = $io->handle;
657             while (<$fh>) {
658             # Process each line after the YAML document
659             }
660            
661             # Write header + body
662             $io->auto_terminate(1);
663             print $io $header;
664             $fh = $io->handle;
665             for (@other_stuff_to_write) {
666             print $fh $_;
667             }
668              
669             =head1 METHODS
670              
671             =over 4
672              
673             =item B
674              
675             $io = IO::YAML->new;
676            
677             # Concise forms
678             $io = IO::YAML->new("$file"); # Default is read-only
679             $io = IO::YAML->new("<$file"); # Read-only made explicit
680             $io = IO::YAML->new(">$file"); # Read-write (empty header & body)
681             $io = IO::YAML->new($file, '<'); # Or '>', '+<', 'r', etc.
682             $io = IO::YAML->new(\*STDIN);
683             $io = IO::YAML->new(\*STDOUT, '>');
684             $io = IO::YAML->new($anything_that_isa_GLOB);
685            
686             # Full-fledged forms
687             $io = IO::YAML->new(
688             'path' => $file, # File will be opened read-only
689             'auto_load' => 1, # Default is 0
690             );
691             $io = IO::YAML->new(
692             'path' => $file, # File will be opened or created
693             'mode' => '>', # Default is '<'; '>>' is also allowed
694             );
695            
696             Instantiate an IO::YAML object. An exception is thrown if anything goes
697             wrong.
698              
699             If a path is specified, the file at that path will be opened. Otherwise,
700             you'll have to open it yourself using the C method.
701              
702             If a path has been specified and the file doesn't already exist, it will be
703             created -- but only if you've specified a mode that permits writing; if you
704             haven't, an exception will be thrown.
705              
706             The following arguments may be specified in the constructor:
707              
708             =over 4
709              
710             =item I
711              
712             Path to a file to create (if it doesn't already exist) and open.
713              
714             =item I
715              
716             Read/write/append mode for the new file. This must be specified in one
717             of the following forms:
718              
719             =over 4
720              
721             =item E
722              
723             =item E
724              
725             =item EE
726              
727             =item r
728              
729             =item w
730              
731             =item a
732              
733             Modes that allow for both reading and writing are not allowed, since YAML
734             documents are variable in size.
735              
736             =back
737              
738             B Numeric modes are not yet implemented.
739              
740             =item I
741              
742             Indicates whether YAML document values should be auto-loaded after being
743             read (see above). The default is B to auto-load values.
744              
745             =item I
746              
747             Indicates whether YAML documents should be auto-terminated when they are
748             written (see above). The default is B to auto-terminate documents.
749              
750             =back
751              
752             =item B
753              
754             $io = IO::YAML->new;
755             $io->open("<$file") or die $!;
756             $io->open($file, $mode) or die $!;
757              
758             Open a file with the specified name and mode. You must use this method
759             if the instance was created without a C element (and one has not
760             been assigned using the C method).
761              
762             Upon failure, sets C<$!> to a meaningful message and returns a false
763             value.
764              
765             The possible modes are as described for B.
766              
767             The C method may be called repeatedly on the same instance,
768             without having to close it.
769              
770             =item B
771              
772             $io->close or die $!;
773              
774             Close the filehandle.
775              
776             =item B
777              
778             $io->print($data) or die $!;
779              
780             =item B
781              
782             =item B
783              
784             =item B
785              
786             $io->seek($pos, $whence);
787              
788             Set the IO::YAML file handle's position I within the YAML stream.
789             This will fail unless it moves the position to the beginning of a YAML document
790             or the end of the whole file handle.
791              
792             =item B
793              
794             $pos = $io->tell;
795              
796             Return the the IO::YAML file handle's position I.
797              
798             =item B
799              
800             $io->truncate(0);
801             $io->truncate($io->tell);
802              
803             Truncates the IO::YAML file to the specified length. As illustrated here, this
804             must be either 0 or equal to the filehandle's current position.
805              
806             =item B
807              
808             if ($io->eof) { ... }
809              
810             Return 1 if the IO::YAML filehandle is at the end of the YAML stream.
811              
812             =back
813              
814             =head1 BUGS
815              
816             Autoflush might not be working.
817              
818             Seeking to the first position beyond the end of the YAML stream should be
819             possible but doesn't currently work.
820              
821             =head1 TO DO
822              
823             Normalize modes passed in the constructor.
824              
825             Implement numeric modes.
826              
827             Add tests for B and B methods.
828              
829             Enable seeking to the first byte beyond the end of the YAML stream.
830              
831             Figure out how to allow read-write access and truncate().
832              
833             =head1 SEE ALSO
834              
835             L
836              
837             =head1 AUTHOR
838              
839             Paul Hoffman (nkuitse AT cpan DOT org)
840              
841             =head1 COPYRIGHT
842              
843             Copyright 2004-2007, 2009 Paul M. Hoffman.
844              
845             This is free software, and is made available under the same terms as
846             Perl itself.
847