File Coverage

blib/lib/List/Enumerator.pm
Criterion Covered Total %
statement 22 22 100.0
branch 6 6 100.0
condition n/a
subroutine 6 6 100.0
pod 1 1 100.0
total 35 35 100.0


line stmt bran cond sub pod time code
1             package List::Enumerator;
2 5     5   15766 use strict;
  5         10  
  5         209  
3 5     5   30 use warnings;
  5         9  
  5         238  
4              
5 5         54 use Sub::Exporter -setup => {
6             exports => [ "E" ],
7             groups => {
8             default => [ "E" ],
9             }
10 5     5   5715 };
  5         77429  
11              
12 5     5   55880 use List::Enumerator::Array;
  5         17  
  5         228  
13 5     5   5199 use List::Enumerator::Sub;
  5         16  
  5         45  
14              
15             our $VERSION = "0.10";
16              
17             sub E {
18 302     302 1 2652 my (@args) = @_;
19 302 100       1147 if (ref($args[0]) eq "ARRAY") {
    100          
    100          
20 35         218 List::Enumerator::Array->new(array => $args[0]);
21             } elsif (ref($args[0]) eq "HASH") {
22 6         12 List::Enumerator::Sub->new(%{ $args[0] });
  6         43  
23             } elsif (ref($args[0]) =~ /^List::Enumerator/) {
24 17         75 $args[0];
25             } else {
26 244         1126 List::Enumerator::Array->new(array => \@args);
27             }
28             }
29              
30              
31             1;
32             __END__
33              
34             =head1 NAME
35              
36             List::Enumerator - list construct library
37              
38             =head1 SYNOPSIS
39              
40             use List::Enumerator qw/E/;
41              
42             my $fizzbuzz =
43             E(1)->countup
44             ->zip(
45             E("", "", "Fizz")->cycle,
46             E("", "", "", "", "Buzz")->cycle
47             )
48             ->map(sub {
49             my ($n, $fizz, $buzz) = @$_;
50             $fizz . $buzz || $n;
51             });
52            
53             $fizzbuzz->take(20)->each(sub {
54             print $_, "\n";
55             });
56              
57              
58             =head1 DESCRIPTION
59              
60             List::Enumerator is list library like Enumerator of Ruby.
61              
62             List::Enumerator::E is interface wrapper for generating List::Enumerator::Array or List::Enumerator::Sub.
63              
64             Most methods (except what returns always infinite list) consider caller context. ex:
65              
66             E(1, 2, 3, 4, 5)->take(3); #=> new List::Enumerator::Sub
67             [ E(1, 2, 3, 4, 5)->take(3) ]; #=> [1, 2, 3]
68              
69             =over
70              
71             =item C<E(list)>
72              
73             =item C<E([arrayref])>
74              
75             Returns List::Enumerator::Array.
76              
77             =item C<E({ next =E<gt> sub {}, rewind =E<gt> sub {} })>
78              
79             Returns List::Enumerator::Sub. ex:
80              
81             use List::Enumerator qw/E/;
82              
83             sub fibonacci {
84             my ($p, $i);
85             E(0, 1)->chain(E({
86             next => sub {
87             my $ret = $p + $i;
88             $p = $i;
89             $i = $ret;
90             $ret;
91             },
92             rewind => sub {
93             ($p, $i) = (0, 1);
94             }
95             }))->rewind;
96             }
97              
98             [ fibonacci->take(10) ]; #=> [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ];
99             [ fibonacci->drop(10)->take(10) ]; #=> [ 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181 ];
100              
101             =item C<next>
102              
103             Returns next element of receiver.
104              
105             =item C<rewind>
106              
107             Rewinds receiver.
108              
109             =item C<select(sub {})>, C<find_all(sub {})>
110              
111             Selects all elements which is evaluated true with block. find_all is just alias to select.
112              
113             E(1..10)->select(sub {
114             $_ % 2 == 0
115             })->to_a; #=> [2, 4, 6, 8, 10];
116              
117              
118             =item C<reject(sub {})>
119              
120             Selects all elements which is evaluated false with block. This is antonym of select.
121              
122              
123             =item C<reduce(sub {})>, C<inject(sub {})>
124              
125             Reduces receiver to one value using block.
126              
127             E(1..3)->reduce(sub { $a + $b }); #=> 6
128              
129              
130             =item C<slice($start, $end)>
131              
132             Slices receiver with $start and $end.
133              
134             E(1..10)->slice(0); #=> 1
135             E(1..10)->slice(-1); #=> 10
136              
137             E(1..20)->slice(9, 11)->to_a; #=> [10, 11, 12]
138              
139              
140             =item C<find($target)>
141              
142             Finds $target. If the value is found returns it. If not so returns undef.
143              
144              
145             =item C<find_index($target)>, C<index_of($target)>
146              
147             Finds $target and returns its index.
148              
149              
150             =item C<first>
151              
152             Returns first element of receiver.
153              
154             =item C<last>
155              
156             Returns last element of receiver.
157              
158             =item C<max>
159              
160             Returns max value of receiver.
161              
162             =item C<max_by(sub {})>
163              
164             Returns max value of receiver with block.
165              
166             =item C<min>
167              
168             Returns min value of receiver.
169              
170             =item C<min_by(sub {})>
171              
172             Returns min value of receiver with block.
173              
174             =item C<minmax_by(sub {})>
175              
176             Returns min value and max value of receiver with block.
177              
178             =item C<sort_by(sub {})>
179              
180             Returns sorted list with returned value from block. (Schwartzian transformed sort)
181              
182             =item C<sort(sub {})>
183              
184             Returns sorted list with block.
185              
186             =item C<sum>
187              
188             Sums receiver up and returns the value.
189              
190             =item C<uniq>
191              
192             Returns new unique list.
193              
194             =item C<grep(sub {})>
195              
196             Grep receiver and returns new list.
197              
198             [ E(1..10)->grep(sub { $_ % 2 == 0 }) ]; #=> [2, 4, 6, 8, 10];
199              
200              
201             =item C<compact>
202              
203             Returns new list excludes undef.
204              
205             =item C<reverse>
206              
207             Returns new reversed list of receiver.
208              
209             =item C<flatten($level)>
210              
211             Expands nested array.
212              
213             [ E([1, 2, [3, 4], 5])->flatten ]; #=> [1, 2, 3, 4, 5];
214             [ E([1, [2, [3, 4]], 5])->flatten ]; #=> [1, 2, 3, 4, 5];
215             [ E([1, [2, [3, 4]], 5])->flatten(1) ]; #=> [1, 2, [3, 4], 5];
216              
217             =item C<length>, C<size>
218              
219             Returns length of receiver. You should not call this method for infinite list.
220              
221             =item C<is_empty>
222              
223             This is synonym of !$self->length;
224              
225             =item C<chain(list...)>
226              
227             Chains with other lists.
228              
229             [ E(1, 2, 3)->chain([4, 5, 6]) ]; #=> [1, 2, 3, 4, 5, 6];
230              
231              
232             =item C<take(sub {})>, C<take(number)>, C<take_while(sub {})>
233              
234             Returns prefix of receiver of length number or elements satisfy block.
235              
236             =item C<drop(sub {})>, C<drop(number)>, C<drop_while(sub {})>
237              
238             Returns remaining of receiver.
239              
240             =item C<every(sub {})>, C<all(sub {})>
241              
242             Returns 1 if all elements in receiver satisfies the block.
243              
244             =item C<some(sub {})>, C<any(sub {})>
245              
246             Returns 1 if at least one element in receiver satisfies the block.
247              
248             =item C<none(sub {})>
249              
250             Returns 1 if all elements in receiver not satisfies the block.
251              
252             E(0, 0, 0, 0)->none; #=> 1
253             E(0, 0, 0, 1)->none; #=> 0
254             E(0, 0, 1, 1)->none; #=> 0
255              
256             =item C<one(sub {})>
257              
258             Returns 1 if just one elements in receiver satisfies the block.
259              
260             E(0, 0, 0, 0)->one; #=> 0
261             E(0, 0, 0, 1)->one; #=> 1
262             E(0, 0, 1, 1)->one; #=> 0
263              
264             =item C<zip(list..)>
265              
266             Returns zipped list with arguments. The length of returned list is length of receiver.
267              
268             [ E(1..3)->zip([qw/a b c/]) ]; #=> [ [1, "a"], [2, "b"], [3, "c"] ]
269              
270              
271             =item C<with_index>
272              
273             Returns zipped with count.
274              
275             E("a", "b", "c")->with_index->each(sub {
276             my ($item, $index) = @$_;
277             });
278              
279              
280             =item C<countup($lim)>, C<to($lim)>
281              
282             Returns count up list starts from first of receiver.
283             If $lim is not supplied, this returns infinite list.
284              
285             E(1)->countup; #=> List::Enumerator::Sub
286             [ E(1)->countup->take(3) ]; #=> [1, 2, 3]
287              
288             E(1)->to(100); #=> E(1..100)
289              
290             =item C<cycle>
291              
292             Returns infinite list which cycles receiver.
293              
294             [ E(1, 2, 3)->cycle->take(5) ]; #=> [1, 2, 3, 1, 2]
295              
296             =item C<join($sep)>
297              
298             Returns string of receiver joined with $sep
299              
300             =item C<group_by(subh{})>
301              
302             Returns a hash reference group by the block.
303              
304             E([
305             { cat => 'a' }, { cat => 'a' },{ cat => 'a' },{ cat => 'a' },
306             { cat => 'b' }, { cat => 'b' },{ cat => 'b' },{ cat => 'b' },
307             { cat => 'c' }, { cat => 'c' },{ cat => 'c' },{ cat => 'c' },
308             ])->group_by(sub {
309             $_->{cat};
310             });
311            
312             {
313             'a' => [ { cat => 'a' }, { cat => 'a' },{ cat => 'a' },{ cat => 'a' } ],
314             'b' => [ { cat => 'b' }, { cat => 'b' },{ cat => 'b' },{ cat => 'b' } ],
315             'c' => [ { cat => 'c' }, { cat => 'c' },{ cat => 'c' },{ cat => 'c' } ],
316             };
317              
318             =item C<partition(sub {})>
319              
320             my ($even, $odd) = E(1..10)->partition(sub { $_ % 2 == 0 });
321              
322             =item C<include($target)>, C<is_include($target)>
323              
324             If receiver include $target this return true.
325              
326             =item C<map(sub {})>, C<collect(sub {})>
327              
328             map.
329              
330             =item C<each(sub {})>
331              
332             Iterate items.
333              
334             =item C<each_index>
335              
336             Iterate indexes with block.
337              
338             =item C<each_slice($n, sub {})>
339              
340             E(1)->countup->each_slice(3)->take(3)->to_a;
341            
342             [
343             [1, 2, 3],
344             [4, 5, 6],
345             [7, 8, 9],
346             ];
347              
348             =item C<each_cons($n, sub {})>
349              
350             E(1)->countup->each_cons(3)->take(3)->to_a;
351            
352             [
353             [1, 2, 3],
354             [2, 3, 4],
355             [3, 4, 5]
356             ];
357              
358             =item C<choice>, C<sample>
359              
360             Returns one item in receiver randomly.
361              
362             =item C<shuffle>
363              
364             Returns randomized array of receiver.
365              
366             =item C<transpose>
367              
368             Returns transposed array of receiver.
369              
370             [ E([
371             [1, 2],
372             [3, 4],
373             [5, 6],
374             ])->transpose ]
375            
376             [
377             [1, 3, 5],
378             [2, 4, 6],
379             ];
380              
381             =item C<to_list>
382              
383             Returns expanded array or array reference.
384              
385             E(1)->countup->take(5)->to_list; #=> [1, 2, 3, 4, 5]
386             [ E(1)->countup->take(5)->to_list ]; #=> [1, 2, 3, 4, 5]
387              
388             =item C<to_a>
389              
390             Returns expanded array reference.
391              
392             E(1)->countup->take(5)->to_a; #=> [1, 2, 3, 4, 5]
393             [ E(1)->countup->take(5)->to_a ]; #=> [ [1, 2, 3, 4, 5] ]
394              
395             =item C<expand>
396              
397             Returns new List::Enumerator::Array with expanded receiver.
398              
399             =item C<dump>
400              
401             Dump receiver.
402              
403             =item C<stop>
404              
405             Throw StopIteration exception.
406              
407             my $list = E({
408             next => sub {
409             $_->stop;
410             }
411             });
412              
413             $list->to_a; #=> [];
414              
415             =back
416              
417              
418             =head2 Concept
419              
420             =over
421              
422             =item * Lazy evaluation for infinite list (ex. cycle)
423              
424             =item * Method chain
425              
426             =item * Read the context
427              
428             =item * Applicable
429              
430             =back
431              
432              
433             =head1 DEVELOPMENT
434              
435             This module is developing on github L<http://github.com/cho45/list-enumerator/tree/master>.
436              
437              
438             =head1 AUTHOR
439              
440             cho45 E<lt>cho45@lowreal.netE<gt>
441              
442             =head1 SEE ALSO
443              
444             L<List::RubyLike>, L<http://coderepos.org/share/wiki/JSEnumerator>
445              
446             =head1 LICENSE
447              
448             This library is free software; you can redistribute it and/or modify
449             it under the same terms as Perl itself.
450              
451             =cut