line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Array::Each; |
2
|
|
|
|
|
|
|
$VERSION = 0.03; |
3
|
8
|
|
|
8
|
|
275167
|
use strict; |
|
8
|
|
|
|
|
23
|
|
|
8
|
|
|
|
|
335
|
|
4
|
8
|
|
|
8
|
|
44
|
use warnings; |
|
8
|
|
|
|
|
16
|
|
|
8
|
|
|
|
|
435
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 NAME |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
Array::Each - iterate over one or more arrays, returning one or more |
9
|
|
|
|
|
|
|
elements from each array followed by the array index. |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 VERSION |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
This document refers to version 0.03 of Array::Each, |
14
|
|
|
|
|
|
|
released March 26, 2004. |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 SYNOPSIS |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use Array::Each; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# one array |
21
|
|
|
|
|
|
|
my @x = qw( a b c d e ); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
my $one = Array::Each->new( \@x ); |
24
|
|
|
|
|
|
|
while( my( $x, $i ) = $one->each() ) { |
25
|
|
|
|
|
|
|
printf "%3d: %s\n", $i, $x; |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# multiple arrays |
29
|
|
|
|
|
|
|
my @y = ( 1,2,3,4,5 ); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
my $set = Array::Each->new( \@x, \@y ); |
32
|
|
|
|
|
|
|
while( my( $x, $y, $i ) = $set->each() ) { |
33
|
|
|
|
|
|
|
printf "%3d: %s %s\n", $i, $x, $y; |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# groups of elements (note set=> parm syntax) |
37
|
|
|
|
|
|
|
my @z = ( a=>1, b=>2, c=>3, d=>4, e=>5 ); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
my $hash_like = Array::Each->new( set=>[\@z], group=>2 ); |
40
|
|
|
|
|
|
|
while( my( $key, $val ) = $hash_like->each() ) { |
41
|
|
|
|
|
|
|
printf "%s => %s\n", $key, $val; |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=cut |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
### more POD follows the __END__ |
47
|
|
|
|
|
|
|
|
48
|
8
|
|
|
8
|
|
44
|
use Carp; |
|
8
|
|
|
|
|
20
|
|
|
8
|
|
|
|
|
886
|
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# object attributes subscript mappings |
51
|
8
|
|
|
8
|
|
47
|
use constant EACH => 0; # sub ref to object's each() |
|
8
|
|
|
|
|
23
|
|
|
8
|
|
|
|
|
860
|
|
52
|
8
|
|
|
8
|
|
42
|
use constant SET => 1; # ref to array of array_refs |
|
8
|
|
|
|
|
13
|
|
|
8
|
|
|
|
|
492
|
|
53
|
8
|
|
|
8
|
|
41
|
use constant ITERATOR => 2; # integer, used as array index |
|
8
|
|
|
|
|
16
|
|
|
8
|
|
|
|
|
383
|
|
54
|
8
|
|
|
8
|
|
58
|
use constant REWIND => 3; # integer, used as array index |
|
8
|
|
|
|
|
33
|
|
|
8
|
|
|
|
|
377
|
|
55
|
8
|
|
|
8
|
|
40
|
use constant BOUND => 4; # boolean, default is true |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
544
|
|
56
|
8
|
|
|
8
|
|
43
|
use constant UNDEF => 5; # scalar value for non-existing elements |
|
8
|
|
|
|
|
20
|
|
|
8
|
|
|
|
|
418
|
|
57
|
8
|
|
|
8
|
|
129
|
use constant STOP => 6; # integer, will compare to iterator |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
513
|
|
58
|
8
|
|
|
8
|
|
38
|
use constant GROUP => 7; # integer, number of elements per group |
|
8
|
|
|
|
|
13
|
|
|
8
|
|
|
|
|
360
|
|
59
|
8
|
|
|
8
|
|
68
|
use constant COUNT => 8; # integer, returned instead of iterator |
|
8
|
|
|
|
|
32
|
|
|
8
|
|
|
|
|
393
|
|
60
|
8
|
|
|
8
|
|
42
|
use constant USER => 9; # reserved for child classes(?) |
|
8
|
|
|
|
|
11
|
|
|
8
|
|
|
|
|
28346
|
|
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# references => names mapping |
63
|
|
|
|
|
|
|
my %_each_subs = ( |
64
|
|
|
|
|
|
|
\&each_default => '&Array::Each::each_default', |
65
|
|
|
|
|
|
|
\&each_unbound => '&Array::Each::each_unbound', |
66
|
|
|
|
|
|
|
\&each_group => '&Array::Each::each_group', |
67
|
|
|
|
|
|
|
\&each_complete => '&Array::Each::each_complete', |
68
|
|
|
|
|
|
|
); |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
# mappings of named arguments |
71
|
|
|
|
|
|
|
my %_index_for; |
72
|
|
|
|
|
|
|
@_index_for{ qw( _each set iterator rewind bound undef stop group count user ) } = |
73
|
|
|
|
|
|
|
( EACH, SET, ITERATOR, REWIND, BOUND, UNDEF, STOP, GROUP, COUNT, USER ); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
my @_default; # see also _set_each() for expectations about defaults |
76
|
|
|
|
|
|
|
@_default[ EACH, SET, ITERATOR, REWIND, BOUND, UNDEF, STOP, GROUP, COUNT, USER ] = |
77
|
|
|
|
|
|
|
( undef, [[]], 0, 0, 1, undef, undef, undef, undef, undef ); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# attribute validations |
80
|
|
|
|
|
|
|
my @_validate; |
81
|
|
|
|
|
|
|
@_validate[ EACH, SET, ITERATOR, REWIND, BOUND, UNDEF, STOP, GROUP, COUNT, USER ] = ( |
82
|
|
|
|
|
|
|
sub{ !defined $_[0] or exists $_each_subs{$_[0]} or |
83
|
|
|
|
|
|
|
croak "Invalid _each: '$_[0]'" }, |
84
|
|
|
|
|
|
|
sub{ UNIVERSAL::isa( $_[0], 'ARRAY' ) and |
85
|
|
|
|
|
|
|
UNIVERSAL::isa( $_[0]->[0], 'ARRAY' ) or |
86
|
|
|
|
|
|
|
croak "Invalid set: '$_[0]'" }, |
87
|
|
|
|
|
|
|
sub{ $_[0] =~ /^\d+$/ or |
88
|
|
|
|
|
|
|
croak "Invalid iterator: '$_[0]'" }, |
89
|
|
|
|
|
|
|
sub{ $_[0] =~ /^\d+$/ or |
90
|
|
|
|
|
|
|
croak "Invalid rewind: '$_[0]'" }, |
91
|
|
|
|
|
|
|
sub{ $_[0] =~ /[01]/ or |
92
|
|
|
|
|
|
|
croak "Invalid bound: '$_[0]'" }, |
93
|
|
|
|
|
|
|
sub{ # Undef value can be anything |
94
|
|
|
|
|
|
|
}, |
95
|
|
|
|
|
|
|
sub{ !defined $_[0] or $_[0] =~ /^\d+$/ or |
96
|
|
|
|
|
|
|
croak "Invalid stop: '$_[0]'" }, |
97
|
|
|
|
|
|
|
sub{ !defined $_[0] or ($_[0] =~ /^\d+$/ and $_[0] > 0) or |
98
|
|
|
|
|
|
|
croak "Invalid group: '$_[0]'" }, |
99
|
|
|
|
|
|
|
sub{ !defined $_[0] or $_[0] =~ /^\d+$/ or |
100
|
|
|
|
|
|
|
croak "Invalid count: '$_[0]'" }, |
101
|
|
|
|
|
|
|
sub {}, # To be defined by child classes |
102
|
|
|
|
|
|
|
); |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# constructor methods: new(), copy() |
105
|
|
|
|
|
|
|
# Note, the code for new() is taken not quite in whole |
106
|
|
|
|
|
|
|
# cloth from section 4.2 of "Object Oriented Perl"[1]. |
107
|
|
|
|
|
|
|
sub new { |
108
|
159
|
|
|
159
|
1
|
83527
|
my $caller = shift; |
109
|
159
|
|
|
|
|
247
|
my $caller_is_obj = ref $caller; |
110
|
159
|
|
66
|
|
|
678
|
my $class = $caller_is_obj || $caller; |
111
|
159
|
|
|
|
|
180
|
my %arg; |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
### if only array refs are passed to new() ... |
114
|
159
|
100
|
|
|
|
323
|
if( ref $_[0] ) { $arg{ 'set' } = [@_] } |
|
6
|
|
|
|
|
19
|
|
115
|
153
|
|
|
|
|
626
|
else { %arg = @_ } |
116
|
|
|
|
|
|
|
|
117
|
159
|
|
|
|
|
408
|
my $self = bless [], $class; |
118
|
159
|
|
|
|
|
596
|
foreach my $member ( keys %_index_for ) { |
119
|
1590
|
|
|
|
|
2015
|
my $index = $_index_for{ $member }; |
120
|
1590
|
100
|
|
|
|
4389
|
if ( exists $arg{ $member } ) { |
|
|
100
|
|
|
|
|
|
121
|
633
|
|
|
|
|
1177
|
$self->[ $index ] = $arg{ $member } } |
122
|
|
|
|
|
|
|
elsif ($caller_is_obj) { |
123
|
60
|
|
|
|
|
83
|
$self->[ $index ] = $caller->[ $index ] } |
124
|
|
|
|
|
|
|
else { |
125
|
897
|
|
|
|
|
1783
|
$self->[ $index ] = $_default[ $index ] } |
126
|
1590
|
|
|
|
|
3251
|
$_validate[ $index ]->( $self->[ $index ] ); |
127
|
|
|
|
|
|
|
} |
128
|
159
|
100
|
|
|
|
858
|
$self->_set_each() unless defined $self->[EACH]; |
129
|
159
|
|
|
|
|
587
|
$self; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
### do not rely on copy() being an alias of new(), see POD |
133
|
|
|
|
|
|
|
*copy = \&new; |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# accessor methods |
136
|
4
|
|
|
4
|
|
40
|
sub _get_each_name { $_each_subs{$_[0]->[EACH]}; } |
137
|
2
|
|
|
2
|
|
427
|
sub _get_each_ref { $_[0]->[EACH] } |
138
|
4
|
|
|
4
|
1
|
395
|
sub get_set { @{$_[0]->[SET]} } |
|
4
|
|
|
|
|
24
|
|
139
|
10
|
|
|
10
|
1
|
3644
|
sub get_iterator { $_[0]->[ITERATOR] } |
140
|
4
|
|
|
4
|
1
|
360
|
sub get_rewind { $_[0]->[REWIND] } |
141
|
4
|
|
|
4
|
1
|
399
|
sub get_bound { $_[0]->[BOUND] } |
142
|
5
|
|
|
5
|
1
|
369
|
sub get_undef { $_[0]->[UNDEF] } |
143
|
4
|
|
|
4
|
1
|
372
|
sub get_stop { $_[0]->[STOP] } |
144
|
4
|
|
|
4
|
1
|
353
|
sub get_group { $_[0]->[GROUP] } |
145
|
4
|
|
|
4
|
1
|
357
|
sub get_count { $_[0]->[COUNT] } |
146
|
2
|
|
|
2
|
0
|
10
|
sub get_user { $_[0]->[USER] } |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
sub _set_each { |
149
|
174
|
|
|
174
|
|
416
|
my $self = shift; |
150
|
174
|
100
|
|
|
|
349
|
if( defined $_[0] ) { |
151
|
2
|
|
|
|
|
4
|
$self->[EACH] = $_[0]; |
152
|
2
|
|
|
|
|
8
|
$_validate[EACH]->( $self->[EACH] ); |
153
|
1
|
|
|
|
|
3
|
return $self->[EACH]; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
# are these set to defaults? |
157
|
172
|
|
|
|
|
277
|
my $r = ( $self->[REWIND] == $_default[REWIND] ); |
158
|
172
|
|
|
|
|
252
|
my $b = ( $self->[BOUND] == $_default[BOUND] ); |
159
|
172
|
|
|
|
|
236
|
my $s = ( !defined $self->[STOP] ); # default is undef |
160
|
172
|
|
|
|
|
418
|
my $g = ( !defined $self->[GROUP] ); # default is undef |
161
|
172
|
|
|
|
|
220
|
my $c = ( !defined $self->[COUNT] ); # default is undef |
162
|
172
|
100
|
100
|
|
|
1085
|
CASE: { |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
163
|
|
|
|
|
|
|
# all are defaults |
164
|
172
|
|
|
|
|
182
|
($r && $b && $s && $g && $c) and |
165
|
|
|
|
|
|
|
$self->[EACH] = \&each_default, last CASE; |
166
|
|
|
|
|
|
|
# all except bound |
167
|
155
|
100
|
100
|
|
|
837
|
($r && $s && $g && $c) and |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
168
|
|
|
|
|
|
|
$self->[EACH] = \&each_unbound, last CASE; |
169
|
|
|
|
|
|
|
# all except group |
170
|
148
|
100
|
100
|
|
|
620
|
($r && $b && $s && $c) and |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
171
|
|
|
|
|
|
|
$self->[EACH] = \&each_group, last CASE; |
172
|
|
|
|
|
|
|
# else |
173
|
140
|
|
|
|
|
2331
|
$self->[EACH] = \&each_complete; |
174
|
|
|
|
|
|
|
} |
175
|
172
|
|
|
|
|
332
|
$self->[EACH]; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub set_set { |
179
|
4
|
|
|
4
|
1
|
1368
|
my $self = shift; |
180
|
4
|
|
|
|
|
13
|
$self->[SET] = [@_]; |
181
|
4
|
|
|
|
|
15
|
$_validate[SET]->( $self->[SET] ); |
182
|
3
|
|
|
|
|
4
|
@{$self->[SET]}; |
|
3
|
|
|
|
|
12
|
|
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
sub set_iterator { |
185
|
248
|
|
|
248
|
1
|
5336
|
my $self = shift; |
186
|
248
|
|
|
|
|
326
|
$self->[ITERATOR] = $_[0]; |
187
|
248
|
|
|
|
|
447
|
$_validate[ITERATOR]->( $self->[ITERATOR] ); |
188
|
247
|
|
|
|
|
902
|
$self->[ITERATOR]; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
sub set_rewind { |
191
|
5
|
|
|
5
|
1
|
786
|
my $self = shift; |
192
|
5
|
|
|
|
|
12
|
$self->[REWIND] = $_[0]; |
193
|
5
|
|
|
|
|
16
|
$_validate[REWIND]->( $self->[REWIND] ); |
194
|
4
|
|
|
|
|
10
|
$self->_set_each; |
195
|
4
|
|
|
|
|
9
|
$self->[REWIND]; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
sub set_bound { |
198
|
2
|
|
|
2
|
1
|
870
|
my $self = shift; |
199
|
2
|
|
|
|
|
7
|
$self->[BOUND] = $_[0]; |
200
|
2
|
|
|
|
|
8
|
$_validate[BOUND]->( $self->[BOUND] ); |
201
|
1
|
|
|
|
|
3
|
$self->_set_each; |
202
|
1
|
|
|
|
|
3
|
$self->[BOUND]; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
sub set_undef { |
205
|
2
|
|
|
2
|
1
|
766
|
my $self = shift; |
206
|
2
|
|
|
|
|
7
|
$self->[UNDEF] = $_[0]; |
207
|
2
|
|
|
|
|
9
|
$_validate[UNDEF]->( $self->[UNDEF] ); |
208
|
2
|
|
|
|
|
5
|
$self->[UNDEF]; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
sub set_stop { |
211
|
8
|
|
|
8
|
1
|
2590
|
my $self = shift; |
212
|
8
|
|
|
|
|
21
|
$self->[STOP] = $_[0]; |
213
|
8
|
|
|
|
|
22
|
$_validate[STOP]->( $self->[STOP] ); |
214
|
7
|
|
|
|
|
18
|
$self->_set_each; |
215
|
7
|
|
|
|
|
17
|
$self->[STOP]; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
sub set_group { |
218
|
6
|
|
|
6
|
1
|
2573
|
my $self = shift; |
219
|
6
|
|
|
|
|
17
|
$self->[GROUP] = $_[0]; |
220
|
6
|
|
|
|
|
22
|
$_validate[GROUP]->( $self->[GROUP] ); |
221
|
5
|
|
|
|
|
14
|
$self->_set_each; |
222
|
5
|
|
|
|
|
11
|
$self->[GROUP]; |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
sub set_count { |
225
|
2
|
|
|
2
|
1
|
898
|
my $self = shift; |
226
|
2
|
|
|
|
|
8
|
$self->[COUNT] = $_[0]; |
227
|
2
|
|
|
|
|
9
|
$_validate[COUNT]->( $self->[COUNT] ); |
228
|
1
|
|
|
|
|
4
|
$self->_set_each; |
229
|
1
|
|
|
|
|
3
|
$self->[COUNT]; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# note: no set_user() defined in this class |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
# utility methods |
235
|
|
|
|
|
|
|
sub rewind { |
236
|
238
|
|
|
238
|
1
|
808
|
my $self = shift; |
237
|
238
|
100
|
|
|
|
663
|
$self->set_iterator( |
238
|
|
|
|
|
|
|
defined $_[0] ? $_[0] : $self->[REWIND] ); |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
sub incr_iterator { |
241
|
1143
|
|
|
1143
|
1
|
1227
|
my $self = shift; |
242
|
1143
|
100
|
|
|
|
3161
|
return $self->[ITERATOR]++ unless $self->[GROUP]; |
243
|
437
|
|
|
|
|
564
|
my $i = $self->[ITERATOR]; |
244
|
437
|
|
|
|
|
571
|
$self->[ITERATOR] += $self->[GROUP]; |
245
|
437
|
|
|
|
|
736
|
$i; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# each methods |
249
|
1323
|
|
|
1323
|
1
|
9402
|
sub each { &{$_[0]->[EACH]} } # call this object's each() |
|
1323
|
|
|
|
|
2876
|
|
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub each_default { # enough attributes are default |
252
|
91
|
|
|
91
|
0
|
101
|
my $self = shift; |
253
|
91
|
|
|
|
|
126
|
my $i = $self->[ITERATOR]++; # inlined incr_iterator |
254
|
155
|
|
|
|
|
405
|
$self->[ITERATOR] = $self->[REWIND], # inlined rewind |
255
|
91
|
100
|
|
|
|
82
|
return if grep {$i >= @$_} @{$self->[SET]}; |
|
91
|
|
|
|
|
133
|
|
256
|
73
|
|
|
|
|
77
|
( (map $_->[$i], @{$self->[SET]}), $i ); |
|
73
|
|
|
|
|
403
|
|
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
sub each_unbound { # bound not true |
260
|
55
|
|
|
55
|
0
|
67
|
my $self = shift; |
261
|
55
|
|
|
|
|
88
|
my $i = $self->[ITERATOR]++; # inlined incr_iterator |
262
|
110
|
|
|
|
|
281
|
$self->[ITERATOR] = $self->[REWIND], # inlined rewind |
263
|
55
|
100
|
|
|
|
54
|
return unless grep {$i < @$_} @{$self->[SET]}; |
|
55
|
|
|
|
|
89
|
|
264
|
46
|
100
|
|
|
|
55
|
( (map {$i<@$_ ? $_->[$i] : $self->[UNDEF]} @{$self->[SET]}), $i ); |
|
92
|
|
|
|
|
305
|
|
|
46
|
|
|
|
|
65
|
|
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
sub each_group { # group is defined |
268
|
36
|
|
|
36
|
0
|
46
|
my $self = shift; |
269
|
36
|
|
|
|
|
42
|
my $group = $self->[GROUP]; |
270
|
36
|
|
|
|
|
48
|
my $i = $self->[ITERATOR]; # inlined |
271
|
36
|
|
|
|
|
47
|
$self->[ITERATOR] += $group; # incr_iterator |
272
|
49
|
|
|
|
|
164
|
$self->[ITERATOR] = $self->[REWIND], # inlined rewind |
273
|
36
|
100
|
|
|
|
36
|
return if grep {$i >= @$_} @{$self->[SET]}; |
|
36
|
|
|
|
|
60
|
|
274
|
28
|
|
|
|
|
33
|
my @ret; |
275
|
28
|
|
|
|
|
30
|
foreach my $aref ( @{$self->[SET]} ) { |
|
28
|
|
|
|
|
52
|
|
276
|
97
|
100
|
|
|
|
255
|
push @ret, |
277
|
37
|
|
|
|
|
69
|
map {$_<@$aref ? $aref->[$_] : $self->[UNDEF]} |
278
|
|
|
|
|
|
|
($i..$i+$group-1) } |
279
|
28
|
|
|
|
|
112
|
( @ret, $i ); |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub each_complete { # enough attributes aren't default |
283
|
1141
|
|
|
1141
|
0
|
1273
|
my $self = shift; |
284
|
1141
|
|
|
|
|
1880
|
my $i = $self->incr_iterator(); # increment for next time, use current |
285
|
1141
|
|
|
|
|
1639
|
my $set = $self->[SET]; |
286
|
1141
|
|
|
|
|
1309
|
my $stop = $self->[STOP]; |
287
|
1141
|
|
|
|
|
1204
|
my $undef = $self->[UNDEF]; |
288
|
1141
|
|
|
|
|
1184
|
my $group = $self->[GROUP]; |
289
|
1141
|
|
|
|
|
1089
|
my $c; |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
# if bound to the shortest array, stop there (or at stop) ... |
292
|
1141
|
100
|
|
|
|
1853
|
if( $self->[BOUND] ) { |
293
|
431
|
100
|
|
|
|
637
|
if( defined $stop ) { |
294
|
240
|
100
|
100
|
|
|
676
|
$self->rewind(), return if $i > $stop || grep {$i >= @$_} @$set } |
|
420
|
|
|
|
|
1338
|
|
295
|
|
|
|
|
|
|
else { |
296
|
191
|
100
|
|
|
|
248
|
$self->rewind(), return if grep {$i >= @$_} @$set } |
|
365
|
|
|
|
|
948
|
|
297
|
320
|
100
|
|
|
|
863
|
$c = defined $self->[COUNT] ? $self->[COUNT]++ : $i; |
298
|
320
|
100
|
|
|
|
1803
|
return ( (map $_->[$i], @$set), $c ) unless defined $group; |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
# else not bound to the shortest array, so (maybe) go farther ... |
302
|
|
|
|
|
|
|
else { |
303
|
710
|
100
|
|
|
|
1036
|
if( defined $stop ) { # may go past longest array, too |
304
|
328
|
100
|
|
|
|
704
|
$self->rewind(), return if $i > $stop } |
305
|
|
|
|
|
|
|
else { |
306
|
382
|
100
|
|
|
|
536
|
$self->rewind(), return unless grep {$i < @$_} @$set } |
|
777
|
|
|
|
|
1976
|
|
307
|
586
|
100
|
|
|
|
1131
|
$c = defined $self->[COUNT] ? $self->[COUNT]++ : $i; |
308
|
586
|
100
|
|
|
|
1203
|
return ( (map {$i<@$_ ? $_->[$i] : $undef} @$set), $c ) |
|
778
|
100
|
|
|
|
2861
|
|
309
|
|
|
|
|
|
|
unless defined $group; |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
# or return groups of elements, i.e., $group is defined |
313
|
318
|
|
|
|
|
392
|
my @ret; |
314
|
318
|
|
|
|
|
468
|
foreach my $aref ( @$set ) { |
315
|
622
|
100
|
|
|
|
1091
|
push @ret, map {$_<@$aref ? $aref->[$_] : $undef} ($i..$i+$group-1) } |
|
1451
|
|
|
|
|
3704
|
|
316
|
318
|
|
|
|
|
1590
|
( @ret, $c ); |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
1; # true |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
__END__ |