File Coverage

blib/lib/IO/YAML.pm
Criterion Covered Total %
statement 190 251 75.7
branch 62 106 58.4
condition 17 45 37.7
subroutine 44 59 74.5
pod 14 27 51.8
total 327 488 67.0


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