File Coverage

lib/IO/Lines.pm
Criterion Covered Total %
statement 41 46 89.1
branch 12 18 66.6
condition 5 9 55.5
subroutine 8 8 100.0
pod 3 3 100.0
total 69 84 82.1


line stmt bran cond sub pod time code
1             package IO::Lines;
2              
3              
4             =head1 NAME
5              
6             IO::Lines - IO:: interface for reading/writing an array of lines
7              
8              
9             =head1 SYNOPSIS
10              
11             use IO::Lines;
12              
13             ### See IO::ScalarArray for details
14              
15              
16             =head1 DESCRIPTION
17              
18             This class implements objects which behave just like FileHandle
19             (or IO::Handle) objects, except that you may use them to write to
20             (or read from) an array of lines. They can be tiehandle'd as well.
21              
22             This is a subclass of L
23             in which the underlying
24             array has its data stored in a line-oriented-format: that is,
25             every element ends in a C<"\n">, with the possible exception of the
26             final element. This makes C I more efficient;
27             if you plan to do line-oriented reading/printing, you want this class.
28              
29             The C method will enforce this rule, so you can print
30             arbitrary data to the line-array: it will break the data at
31             newlines appropriately.
32              
33             See L for full usage and warnings.
34              
35             =cut
36              
37 2     2   1324 use Carp;
  2         1  
  2         90  
38 2     2   8 use strict;
  2         2  
  2         35  
39 2     2   304 use IO::ScalarArray;
  2         2  
  2         63  
40 2     2   6 use vars qw($VERSION @ISA);
  2         2  
  2         650  
41              
42             # The package version, both in 1.23 style *and* usable by MakeMaker:
43             $VERSION = "2.111";
44              
45             # Inheritance:
46             @ISA = qw(IO::ScalarArray); ### also gets us new_tie :-)
47              
48              
49             #------------------------------
50             #
51             # getline
52             #
53             # Instance method, override.
54             # Return the next line, or undef on end of data.
55             # Can safely be called in an array context.
56             # Currently, lines are delimited by "\n".
57             #
58             sub getline {
59 29     29 1 671 my $self = shift;
60              
61 29 100       64 if (!defined $/) {
    50          
62 2         3 return join( '', $self->_getlines_for_newlines );
63             }
64             elsif ($/ eq "\n") {
65 27 100       68 if (!*$self->{Pos}) { ### full line...
66 26         72 return *$self->{AR}[*$self->{Str}++];
67             }
68             else { ### partial line...
69 1         6 my $partial = substr(*$self->{AR}[*$self->{Str}++], *$self->{Pos});
70 1         2 *$self->{Pos} = 0;
71 1         2 return $partial;
72             }
73             }
74             else {
75 0         0 croak 'unsupported $/: must be "\n" or undef';
76             }
77             }
78              
79             #------------------------------
80             #
81             # getlines
82             #
83             # Instance method, override.
84             # Return an array comprised of the remaining lines, or () on end of data.
85             # Must be called in an array context.
86             # Currently, lines are delimited by "\n".
87             #
88             sub getlines {
89 2     2 1 4 my $self = shift;
90 2 50       4 wantarray or croak("can't call getlines in scalar context!");
91              
92 2 50 33     8 if ((defined $/) and ($/ eq "\n")) {
93 2         5 return $self->_getlines_for_newlines(@_);
94             }
95             else { ### slow but steady
96 0         0 return $self->SUPER::getlines(@_);
97             }
98             }
99              
100             #------------------------------
101             #
102             # _getlines_for_newlines
103             #
104             # Instance method, private.
105             # If $/ is newline, do fast getlines.
106             # This CAN NOT invoke getline!
107             #
108             sub _getlines_for_newlines {
109 4     4   4 my $self = shift;
110 4         5 my ($rArray, $Str, $Pos) = @{*$self}{ qw( AR Str Pos ) };
  4         7  
111 4         4 my @partial = ();
112              
113 4 50       7 if ($Pos) { ### partial line...
114 0         0 @partial = (substr( $rArray->[ $Str++ ], $Pos ));
115 0         0 *$self->{Pos} = 0;
116             }
117 4         7 *$self->{Str} = scalar @$rArray; ### about to exhaust @$rArray
118 4         28 return (@partial,
119             @$rArray[ $Str .. $#$rArray ]); ### remaining full lines...
120             }
121              
122             #------------------------------
123             #
124             # print ARGS...
125             #
126             # Instance method, override.
127             # Print ARGS to the underlying line array.
128             #
129             sub print {
130 7 50 33 7 1 67 if (defined $\ && $\ ne "\n") {
131 0         0 croak 'unsupported $\: must be "\n" or undef';
132             }
133              
134 7         6 my $self = shift;
135             ### print STDERR "\n[[ARRAY WAS...\n", @{*$self->{AR}}, "<>\n";
136 7 50       21 my @lines = split /^/, join('', @_); @lines or return 1;
  7         10  
137              
138             ### Did the previous print not end with a newline?
139             ### If so, append first line:
140 7 100 100     6 if (@{*$self->{AR}} and (*$self->{AR}[-1] !~ /\n\Z/)) {
  7         48  
141 4         7 *$self->{AR}[-1] .= shift @lines;
142             }
143 7         8 push @{*$self->{AR}}, @lines; ### add the remainder
  7         15  
144             ### print STDERR "\n[[ARRAY IS NOW...\n", @{*$self->{AR}}, "<>\n";
145 7         19 1;
146             }
147              
148             #------------------------------
149             1;
150              
151             __END__