File Coverage

blib/lib/Launcher/Cascade/FileReader/Seekable.pm
Criterion Covered Total %
statement 20 26 76.9
branch 3 6 50.0
condition 2 5 40.0
subroutine 6 7 85.7
pod 2 2 100.0
total 33 46 71.7


line stmt bran cond sub pod time code
1             package Launcher::Cascade::FileReader::Seekable;
2              
3             =head1 NAME
4              
5             Launcher::Cascade::FileReader::Seekable - a filereader that memorizes its position between reads.
6              
7             =head1 SYNOPSIS
8              
9             use Launcher::Cascade::FileReader::Seekable;
10              
11             my $f = new Launcher::Cascade::FileReader -path => ... ;
12              
13             my $fh1 = $f->open();
14             my $line1 = <$fh1>; # first line
15             $f->close();
16              
17             # later, in a nearby piece of code
18              
19             my $fh2 = $f->open(); # different filehandle
20             my $line2 = <$fh2>; # next line
21              
22              
23             =head1 DESCRIPTION
24              
25             Launcher::Cascade::FileReader::Seekable inherits from
26             Launcher::Cascade::FileReader but keeps in memory the position where it was at
27             when the filehandle is closed. Subsequent calls to open() will perform the
28             necessary operations to resume reading where it last stopped, be it when
29             reading a local file, or a remote file through ssh.
30              
31             =cut
32              
33 2     2   23916 use strict;
  2         4  
  2         67  
34 2     2   11 use warnings;
  2         3  
  2         55  
35              
36 2     2   10 use base qw( Launcher::Cascade::FileReader );
  2         4  
  2         651  
37              
38 2     2   2109 use IO::Handle;
  2         15423  
  2         500  
39              
40             =head2 Attributes
41              
42             =over 4
43              
44             =item B
45              
46             =back
47              
48             =cut
49             Launcher::Cascade::make_accessors qw( position );
50              
51             =head2 Methods
52              
53             =cut
54              
55             # _remote_cat: the command to launch remotely to read a file over ssh
56             # either return a regular 'cat' if one wants to start from the start, or a Perl
57             # one-liner to first seek the wanted position.
58             sub _remote_cat {
59              
60 0     0   0 my $self = shift;
61 0         0 my $path = shift;
62              
63 0         0 my $pos = $self->position();
64              
65 0 0       0 if ( $pos ) {
66 0         0 return qq#perl -e "open IN,q{<},pop;seek IN,pop,0;print while " $pos $path#
67             }
68             else {
69 0         0 return $self->SUPER::_remote_cat($path);
70             }
71             }
72              
73             =over 4
74              
75             =item B
76              
77             Stores the filehandle's position in the position() attribute, then closes the
78             filehandle.
79              
80             =cut
81              
82             sub close {
83              
84 1     1 1 1045 my $self = shift;
85 1 50 0     6 $self->position(tell($self->filehandle()) + ($self->host() ? $self->position() || 0 : 0));
86 1         11 $self->SUPER::close();
87             }
88              
89             =item B
90              
91             Opens the file (locally or remotely), seeks to the desired position() and
92             returns a filehandle.
93              
94             =cut
95              
96             sub open {
97              
98 2     2 1 13 my $self = shift;
99 2         14 my $fh = $self->SUPER::open();
100              
101 2 100 66     10 if ( $self->position() && !$self->host() ) {
102 1         10 seek $fh, $self->position(), 0;
103             }
104 2         6 return $fh;
105             }
106              
107             =back
108              
109             =head1 BUGS AND CAVEATS
110              
111             =over 4
112              
113             =item *
114              
115             C has to be in a directory mentioned in the C environment variable
116             on the remote host, because the C operation on remote files is performed
117             with a Perl one-liner.
118              
119             =item *
120              
121             The memorization of the position is performed only when closing the filehandle
122             through the close() method of Launcher::Cascade::FileReader::Seekable, not when
123             closing the filehandle directly:
124              
125             my $fh = $f->open();
126             ... # do something with it
127              
128             $f->close(); # right: position() is updated
129             close $fh; # wrong: position() is *not* updated
130              
131             =back
132              
133             =head1 SEE ALSO
134              
135             L
136              
137             =head1 AUTHOR
138              
139             Cédric Bouvier C<< >>
140              
141             =head1 COPYRIGHT & LICENSE
142              
143             Copyright (C) 2006 Cédric Bouvier, All Rights Reserved.
144              
145             This program is free software; you can redistribute it and/or modify it under
146             the same terms as Perl itself.
147              
148             =cut
149              
150             1; # end of Launcher::Cascade::FileReader::Seekable