annotate variant_effect_predictor/Bio/EnsEMBL/Utils/Iterator.pm @ 3:d30fa12e4cc5 default tip

Merge heads 2:a5976b2dce6f and 1:09613ce8151e which were created as a result of a recently fixed bug.
author devteam <devteam@galaxyproject.org>
date Mon, 13 Jan 2014 10:38:30 -0500
parents 1f6dce3d34e0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1 package Bio::EnsEMBL::Utils::Iterator;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
2
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
3 =head1 LICENSE
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
4
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
5 Copyright (c) 1999-2012 The European Bioinformatics Institute and
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
6 Genome Research Limited. All rights reserved.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
7
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
8 This software is distributed under a modified Apache license.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
9 For license details, please see
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
10
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
11 http://www.ensembl.org/info/about/code_licence.html
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
12
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
13 =head1 CONTACT
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
14
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
15 Please email comments or questions to the public Ensembl
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
16 developers list at <dev@ensembl.org>.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
17
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
18 Questions may also be sent to the Ensembl help desk at
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
19 <helpdesk@ensembl.org>.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
20
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
21 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
22
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
23 =head1 NAME
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
24
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
25 Bio::EnsEMBL::Utils::Iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
26
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
27 =head1 SYNOPSIS
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
28
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
29 my $variation_iterator =
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
30 $variation_adaptor->fetch_Iterator_by_VariationSet($1kg_set);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
31
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
32 while ( my $variation = $variation_iterator->next ) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
33 # operate on variation object
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
34 print $variation->name, "\n";
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
35 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
36
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
37 =head1 DESCRIPTION
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
38
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
39 Some adaptor methods may return more objects than can fit in memory at once, in these cases
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
40 you can fetch an iterator object instead of the usual array reference. The iterator object
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
41 allows you to iterate over the set of objects (using the next() method) without loading the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
42 entire set into memory at once. You can tell if an iterator is exhausted with the has_next()
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
43 method. The peek() method allows you to fetch the next object from the iterator without
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
44 advancing the iterator - this is useful if you want to check some property of en element in
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
45 the set while leaving the iterator unchanged.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
46
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
47 You can filter and transform an iterator in an analogous way to using map and grep on arrays
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
48 using the provided map() and grep() methods. These methods return another iterator, and only
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
49 perform the filtering and transformation on each element as it is requested, so again these
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
50 can be used without loading the entire set into memory.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
51
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
52 Iterators can be combined together with the append() method which merges together the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
53 iterator it is called on with the list of iterators passed in as arguments. This is
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
54 somewhat analogous to concatenating arrays with the push function. append() returns a new
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
55 iterator which iterates over each component iterator until it is exhausted before moving
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
56 on to the next iterator, in the order in which they are supplied to the method.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
57
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
58 An iterator can be converted to an array (reference) containing all the elements in the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
59 set with the to_arrayref() method, but note that this array may consume a lot of memory if
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
60 the set the iterator is iterating over is large and it is recommended that you do not call
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
61 this method unless there is no way of working with each element at a time.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
62
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
63 =head1 METHODS
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
64
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
65 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
66
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
67 use strict;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
68 use warnings;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
69
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
70 use Bio::EnsEMBL::Utils::Exception qw(throw);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
71
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
72 =head2 new
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
73
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
74 Argument : either a coderef representing the iterator, in which case this
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
75 anonymous subroutine is assumed to return the next object in the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
76 set when called and to return undef when the set is exhausted,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
77 or an arrayref, in which case we return an iterator over this
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
78 array. If the argument is not defined then we return an 'empty'
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
79 iterator that immediately returns undef
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
80
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
81 Example :
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
82
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
83 my @dbIDs = fetch_relevant_dbIDs();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
84
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
85 my $iterator = Bio::EnsEMBL::Utils::Iterator->new(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
86 sub { return $self->fetch_by_dbID(shift @dbIDs) }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
87 );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
88
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
89 NB: this is a very simple example showing how to call the constructor
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
90 that would be rather inefficient in practice, real examples should
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
91 probably be smarter about batching up queries to minimise trips to
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
92 the database. See examples in the Variation API.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
93
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
94 Description: Constructor, creates a new iterator object
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
95 Returntype : Bio::EnsEMBL::Utils::Iterator instance
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
96 Exceptions : thrown if the supplied argument is not the expected
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
97 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
98 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
99
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
100 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
101
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
102 sub new {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
103 my $class = shift;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
104
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
105 my $arg = shift;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
106
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
107 my $coderef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
108
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
109 if (not defined $arg) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
110 # if the user doesn't supply an argument, we create a
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
111 # simple 'empty' iterator that immediately returns undef
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
112
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
113 $coderef = sub { return undef };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
114 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
115 elsif (ref $arg eq 'ARRAY') {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
116 # if the user supplies an arrayref as an argument, we
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
117 # create an iterator over this array
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
118
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
119 $coderef = sub { return shift @$arg };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
120 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
121 elsif (ref $arg eq 'CODE'){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
122 $coderef = $arg;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
123 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
124 else {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
125 throw("The supplied argument does not look like an arrayref or a coderef ".(ref $arg))
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
126 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
127
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
128 my $self = {sub => $coderef};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
129
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
130 return bless $self, $class;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
131 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
132
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
133
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
134 =head2 next
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
135
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
136 Example : $obj = $iterator->next
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
137 Description: returns the next object from this iterator, or undef if the iterator is exhausted
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
138 Returntype : Object type will depend on what this iterator is iterating over
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
139 Exceptions : none
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
140 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
141 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
142
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
143 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
144
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
145 sub next {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
146 my $self = shift;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
147
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
148 $self->{next} = $self->{sub}->() unless defined $self->{next};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
149
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
150 return delete $self->{next};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
151 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
152
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
153 =head2 has_next
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
154
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
155 Example : if ($iterator->has_next) { my $obj = $iterator->next }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
156 Description: Boolean - true if this iterator has more elements to fetch, false when
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
157 it is exhausted
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
158 Returntype : boolean
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
159 Exceptions : none
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
160 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
161 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
162
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
163 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
164
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
165 sub has_next {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
166 my $self = shift;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
167
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
168 $self->{next} = $self->{sub}->() unless defined $self->{next};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
169
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
170 return defined $self->{next};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
171 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
172
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
173 =head2 peek
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
174
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
175 Example : $obj = $iterator->peek
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
176 Description: returns the next object from this iterator, or undef if the iterator is exhausted,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
177 much like next but does not advance the iterator (so the same object will be
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
178 returned on the following call to next or peek)
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
179 Returntype : Object type will depend on what this iterator is iterating over
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
180 Exceptions : none
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
181 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
182 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
183
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
184 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
185
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
186 sub peek {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
187 my $self = shift;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
188
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
189 $self->{next} = $self->{sub}->() unless defined $self->{next};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
190
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
191 return $self->{next};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
192 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
193
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
194 =head2 grep
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
195
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
196 Example : my $filtered_iterator = $original_iterator->grep(sub {$_->name =~ /^rs/});
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
197 Description: filter this iterator, returning another iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
198 Argument : a coderef which returns true if the element should be included in the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
199 filtered set, or false if the element should be filtered out. $_ will be
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
200 set locally to each element in turn so you should be able to write a block
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
201 in a similar way as for the perl grep function (although it will need to be
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
202 preceded with the sub keyword). Otherwise you can pass in a reference to a
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
203 subroutine which expects a single argument with the same behaviour.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
204 Returntype : Bio::EnsEMBL::Utils::Iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
205 Exceptions : thrown if the argument is not a coderef
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
206 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
207 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
208
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
209 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
210
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
211 sub grep {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
212 my ($self, $coderef) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
213
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
214 throw('Argument should be a coderef') unless ref $coderef eq 'CODE';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
215
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
216 return Bio::EnsEMBL::Utils::Iterator->new(sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
217 while ($self->has_next) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
218 local $_ = $self->next;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
219 return $_ if $coderef->($_);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
220 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
221 return undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
222 });
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
223 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
224
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
225 =head2 map
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
226
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
227 Example : my $transformed_iterator = $original_iterator->map(sub {$_->name});
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
228 Description: transform the elements of this iterator, returning another iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
229 Argument : a coderef which returns the desired transformation of each element.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
230 $_ will be set locally set to each original element in turn so you
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
231 should be able to write a block in a similar way as for the perl map
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
232 function (although it will need to be preceded with the sub keyword).
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
233 Otherwise you can pass in a reference to a subroutine which expects a
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
234 single argument with the same behaviour.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
235 Returntype : Bio::EnsEMBL::Utils::Iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
236 Exceptions : thrown if the argument is not a coderef
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
237 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
238 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
239
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
240 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
241
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
242
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
243 sub map {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
244 my ($self, $coderef) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
245
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
246 throw('Argument should be a coderef') unless ref $coderef eq 'CODE';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
247
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
248 return Bio::EnsEMBL::Utils::Iterator->new(sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
249 local $_ = $self->next;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
250 return defined $_ ? $coderef->($_) : undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
251 });
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
252 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
253
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
254
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
255 =head2 each
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
256
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
257 Example : $iterator->each(sub { print $_->name, "\n"; });
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
258 Description: Performs a full iteration of the current iterator instance.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
259 Argument : a coderef which returns the desired transformation of each element.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
260 $_ will be set locally set to each element.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
261 Returntype : None
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
262 Exceptions : thrown if the argument is not a coderef
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
263 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
264 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
265
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
266 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
267
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
268
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
269 sub each {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
270 my ($self, $coderef) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
271 throw('Argument should be a coderef') unless ref $coderef eq 'CODE';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
272 while($self->has_next()) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
273 local $_ = $self->next();
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
274 $coderef->($_);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
275 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
276 return;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
277 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
278
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
279
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
280 =head2 to_arrayref
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
281
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
282 Example : my $arrayref = $iterator->to_arrayref;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
283 Description: return a reference to an array containing all elements from the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
284 iterator. This is created by simply iterating over the iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
285 until it is exhausted and adding each element in turn to an array.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
286 Note that this may consume a lot of memory for iterators over
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
287 large collections
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
288 Returntype : arrayref
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
289 Exceptions : none
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
290 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
291 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
292
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
293 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
294
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
295 sub to_arrayref {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
296 my ($self) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
297
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
298 my @array;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
299
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
300 while ($self->has_next) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
301 push @array, $self->next;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
302 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
303
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
304 return \@array;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
305 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
306
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
307 =head2 append
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
308
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
309 Example : my $combined_iterator = $iterator1->append($iterator2, $iterator3);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
310 Description: return a new iterator that combines this iterator with the others
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
311 passed as arguments, this new iterator will iterate over each
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
312 component iterator (in the order supplied here) until it is
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
313 exhausted and then move on to the next iterator until all are
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
314 exhausted
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
315 Argument : an array of Bio::EnsEMBL::Utils::Iterator objects
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
316 Returntype : Bio::EnsEMBL::Utils::Iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
317 Exceptions : thrown if any of the arguments are not iterators
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
318 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
319 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
320
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
321 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
322
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
323 sub append {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
324 my ($self, @queue) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
325
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
326 for my $iterator (@queue) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
327 throw("Argument to append doesn't look like an iterator")
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
328 unless UNIVERSAL::can($iterator, 'has_next') && UNIVERSAL::can($iterator, 'next');
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
329 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
330
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
331 # push ourselves onto the front of the queue
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
332 unshift @queue, $self;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
333
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
334 return Bio::EnsEMBL::Utils::Iterator->new(sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
335 # shift off any exhausted iterators
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
336 while (@queue && not $queue[0]->has_next) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
337 shift @queue;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
338 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
339
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
340 # and return the next object from the iterator at the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
341 # head of the queue, or undef if the queue is empty
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
342 return @queue ? $queue[0]->next : undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
343 });
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
344 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
345
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
346 =head2 take
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
347
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
348 Example : my $limited_iterator = $iterator->take(5);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
349 Description: return a new iterator that only iterates over the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
350 first n elements of this iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
351 Argument : a positive integer
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
352 Returntype : Bio::EnsEMBL::Utils::Iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
353 Exceptions : thrown if the argument is negative
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
354 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
355 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
356
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
357 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
358
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
359 sub take {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
360 my ($self, $n) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
361
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
362 throw("Argument cannot be negative") if $n < 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
363
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
364 my $cnt = 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
365
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
366 return Bio::EnsEMBL::Utils::Iterator->new(sub {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
367 return $cnt++ >= $n ? undef : $self->next;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
368 });
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
369 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
370
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
371 =head2 skip
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
372
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
373 Example : my $limited_iterator = $iterator->skip(5);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
374 Description: skip over the first n elements of this iterator (and then return
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
375 the same iterator for your method chaining convenience)
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
376 Argument : a positive integer
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
377 Returntype : Bio::EnsEMBL::Utils::Iterator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
378 Exceptions : thrown if the argument is negative
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
379 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
380 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
381
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
382 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
383
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
384 sub skip {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
385 my ($self, $n) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
386
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
387 throw("Argument cannot be negative") if $n < 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
388
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
389 $self->next for (0 .. $n-1);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
390
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
391 return $self;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
392 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
393
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
394 =head2 reduce
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
395
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
396 Example : my $tot_length = $iterator->reduce(sub { $_[0] + $_[1]->length }, 0);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
397 Description: reduce this iterator with the provided coderef, using the (optional)
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
398 second argument as the initial value of the accumulator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
399 Argument[1]: a coderef that expects 2 arguments, the current accumulator
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
400 value and the next element in the set, and returns the next
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
401 accumulator value. Unless the optional second argument is
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
402 provided the first accumulator value passed in will be the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
403 first element in the set
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
404 Argument[2]: (optional) an initial value to use for the accumulator instead
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
405 of the first value of the set
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
406 Returntype : returntype of the coderef
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
407 Exceptions : thrown if the argument is not a coderef
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
408 Caller : general
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
409 Status : Experimental
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
410
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
411 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
412
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
413 sub reduce {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
414 my ($self, $coderef, $init_val) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
415
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
416 throw('Argument should be a coderef') unless ref $coderef eq 'CODE';
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
417
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
418 my $result = defined $init_val ? $init_val : $self->next;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
419
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
420 while ($self->has_next) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
421 $result = $coderef->($result, $self->next);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
422 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
423
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
424 return $result;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
425 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
426
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
427 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
428