File Coverage

blib/lib/Data/Perl/Role/Collection/Array.pm
Criterion Covered Total %
statement 115 117 98.2
branch 43 52 82.6
condition 3 3 100.0
subroutine 39 40 97.5
pod 32 32 100.0
total 232 244 95.0


line stmt bran cond sub pod time code
1             package Data::Perl::Role::Collection::Array;
2             $Data::Perl::Role::Collection::Array::VERSION = '0.002011';
3             # ABSTRACT: Wrapping class for Perl's built in array structure.
4              
5 9     9   4500 use strictures 1;
  9         60  
  9         400  
6              
7 9     9   826 use Role::Tiny;
  9         20  
  9         43  
8 9     9   1417 use List::Util;
  9         20  
  9         799  
9 9     9   4965 use List::MoreUtils;
  9         111712  
  9         58  
10 9     9   8636 use Scalar::Util qw/blessed/;
  9         22  
  9         1450  
11              
12             sub new {
13 101     101 1 3108 my $cl = CORE::shift; bless([ @_ ], $cl)
  101         461  
14             }
15              
16             # find the package name if possible else default to __PACKAGE__
17             #sub _blessed { blessed($_[0]) || __PACKAGE__ }
18              
19 32     32 1 73 sub count { CORE::scalar @{$_[0]} }
  32         100  
20              
21 2 100   2 1 4 sub is_empty { CORE::scalar @{$_[0]} ? 0 : 1 }
  2         11  
22              
23             {
24 9     9   65 no warnings 'once';
  9         51  
  9         14899  
25 55     55 1 105 sub all { @{$_[0]} }
  55         284  
26              
27             *elements = *all;
28             *flatten = *all;
29             }
30              
31 2     2 1 9 sub get { $_[0]->[ $_[1] ] }
32              
33 2     2 1 5 sub pop { CORE::pop @{$_[0]} }
  2         11  
34              
35 1     1 1 6 sub push { CORE::push @{$_[0]}, @_[1..$#_] }
  1         8  
36              
37 1     1 1 5 sub shift { CORE::shift @{$_[0]} }
  1         7  
38              
39 1     1 1 6 sub unshift { CORE::unshift @{$_[0]}, @_[1..$#_] }
  1         5  
40              
41 0     0 1 0 sub clear { @{$_[0]} = () }
  0         0  
42              
43 4     4 1 1136 sub first { &List::Util::first($_[1], @{$_[0]}) }
  4         17  
44              
45 4     4 1 1370 sub first_index { &List::MoreUtils::first_index($_[1], @{$_[0]}) }
  4         21  
46              
47 4     4 1 14 sub reduce { List::Util::reduce { $_[1]->($a, $b) } @{$_[0]} }
  1     1   10  
  1         8  
48              
49 3     3 1 1153 sub set { $_[0]->[ $_[1] ] = $_[2] }
50              
51             sub accessor {
52 5 100   5 1 578 if (@_ == 2) {
    100          
53 2         9 $_[0]->[$_[1]];
54             }
55             elsif (@_ > 2) {
56 2         6 $_[0]->[$_[1]] = $_[2];
57             }
58             }
59              
60             sub natatime {
61 2     2 1 1571 my $iter = List::MoreUtils::natatime($_[1], @{$_[0]});
  2         21  
62              
63 2 100       8 if ($_[2]) {
64 1         10 while (my @vals = $iter->()) {
65 1         4 $_[2]->(@vals);
66             }
67             }
68             else {
69 1         4 $iter;
70             }
71             }
72              
73 2 100   2 1 16 sub shallow_clone { blessed($_[0]) ? bless([@{$_[0]}], ref $_[0]) : [@{$_[0]}] }
  1         5  
  1         4  
74              
75             # Data::Collection methods that return a Data::Perl::Collection::Array object
76             #sub members {
77             # my ($self) = @_;
78             # qw/map grep member_count sort reverse print any all one none join/;
79             #}
80              
81              
82             sub map {
83 2     2 1 528 my ($self, $cb) = @_;
84              
85 2         5 my @res = CORE::map { $cb->($_) } @$self;
  6         21  
86              
87 2 50       20 blessed($self) ? blessed($self)->new(@res) : @res;
88             }
89              
90             sub grep {
91 6     6 1 22 my ($self, $cb) = @_;
92              
93 6         14 my @res = CORE::grep { $cb->($_) } @$self;
  54         164  
94              
95 6 50       53 blessed($self) ? blessed($self)->new(@res) : @res;
96             }
97              
98             sub sort {
99 6     6 1 36 my ($self, $cb) = @_;
100              
101 6 100       29 my @res = $cb ? CORE::sort { $cb->($a, $b) } @$self : CORE::sort @$self;
  15         49  
102              
103 6 50       46 blessed($self) ? blessed($self)->new(@res) : @res;
104             }
105              
106             sub reverse {
107 1     1 1 8 my ($self) = @_;
108              
109 1         4 my @res = CORE::reverse @$self;
110              
111 1 50       13 blessed($self) ? blessed($self)->new(@res) : @res;
112             }
113              
114             sub sort_in_place {
115 2 100   2 1 16 @{$_[0]} = ($_[1] ? sort { $_[1]->($a, $b) } @{$_[0]} : sort @{$_[0]});
  2         10  
  8         21  
  1         5  
  1         7  
116 2         6 $_[0];
117             }
118              
119             sub splice {
120 2     2 1 15 my ($self) = @_;
121              
122 2         3 my @res = CORE::splice @{$_[0]}, $_[1], $_[2], @_[3..$#_];
  2         11  
123              
124 2 50       16 blessed($self) ? blessed($self)->new(@res) : @res;
125             }
126              
127             sub shuffle {
128 2     2 1 10 my ($self) = @_;
129              
130 2         45 my @res = List::Util::shuffle(@$self);
131              
132 2 50       16 blessed($self) ? blessed($self)->new(@res) : @res;
133             }
134              
135             sub uniq {
136 1     1 1 8 my ($self) = @_;
137              
138 1         11 my @res = List::MoreUtils::uniq(@$self);
139              
140 1 50       12 blessed($self) ? blessed($self)->new(@res) : @res;
141             }
142              
143             sub delete {
144 1     1 1 7 my ($self, $idx) = @_;
145              
146 1         4 my ($res) = CORE::splice(@$self, $idx, 1);
147              
148 1         3 $res;
149             }
150              
151             sub insert {
152 1     1 1 8 my ($self, $idx, $el) = @_;
153              
154 1         5 my ($res) = CORE::splice(@$self, $idx, 0, $el);
155              
156 1         3 $res;
157             }
158              
159             sub flatten_deep {
160 2     2 1 5 my ($self, $depth) = @_;
161              
162 2         7 _flatten_deep(@$self, $depth);
163             }
164              
165             sub _flatten_deep {
166 7     7   16 my @array = @_;
167 7         10 my $depth = CORE::pop @array;
168 7 100       16 --$depth if (defined($depth));
169              
170             my @elements = CORE::map {
171 7 100 100     14 (ref eq 'ARRAY')
  17 100       77  
172             ? (defined($depth) && $depth == -1) ? $_ : _flatten_deep( @$_, $depth )
173             : $_
174             } @array;
175             }
176              
177             sub join {
178 4     4 1 16 my ($self, $with) = @_;
179              
180 4 100       27 CORE::join((defined $with ? $with : ','), @$self);
181             }
182              
183             sub print {
184 3     3 1 2745 my ($self, $fh, $arg) = @_;
185              
186 3 100       7 print { $fh || *STDOUT } CORE::join((defined $arg ? $arg : ','), @$self);
  3 100       136  
187             }
188              
189             sub head {
190 5     5 1 18 my ($self, $count) = @_;
191              
192 5 100       15 $count = $self->count if $count > $self->count;
193 5 100       17 $count = $self->count - -$count if $count < 0;
194              
195 5         17 my @res = ($self->elements)[0 .. $count - 1];
196              
197 5 50       34 blessed($self) ? blessed($self)->new(@res) : @res;
198             }
199              
200             sub tail {
201 5     5 1 12 my ($self, $count) = @_;
202              
203 5 100       14 $count = $self->count if $count > $self->count;
204 5 100       16 $count = $self->count - -$count if $count < 0;
205 5         9 my $start = $self->count - $count;
206              
207 5         12 my @res = ($self->elements)[$start .. $self->count - 1];
208              
209 5 50       34 blessed($self) ? blessed($self)->new(@res) : @res;
210             }
211              
212             1;
213              
214             =pod
215              
216             =encoding UTF-8
217              
218             =head1 NAME
219              
220             Data::Perl::Role::Collection::Array - Wrapping class for Perl's built in array structure.
221              
222             =head1 VERSION
223              
224             version 0.002011
225              
226             =head1 SYNOPSIS
227              
228             use Data::Perl qw/array/;
229              
230             my $array = array(1, 2, 3);
231              
232             $array->push(5);
233              
234             $array->grep(sub { $_ > 2 })->map(sub { $_ ** 2 })->elements; # (3, 5);
235              
236             =head1 DESCRIPTION
237              
238             This class provides a wrapper and methods for interacting with an array.
239             All methods that return a list do so via a Data::Perl::Collection::Array object.
240              
241             =head1 PROVIDED METHODS
242              
243             =over 4
244              
245             =item B
246              
247             Constructs a new Data::Perl::Collection::Array object initialized with passed
248             in values, and returns it.
249              
250             =item B
251              
252             Returns the number of elements in the array.
253              
254             $stuff = Data::Perl::Collection::Array->new(qw/foo bar baz boo/);
255              
256             print $stuff->count; # prints 4
257              
258             This method does not accept any arguments.
259              
260             =item B
261              
262             Returns a boolean value that is true when the array has no elements.
263              
264             $stuff->is_empty ? die "No options!\n" : print "Good boy.\n";
265              
266             This method does not accept any arguments.
267              
268             =item B
269              
270             Returns all of the elements of the array as an array (not an array reference).
271              
272             my @options = $stuff->elements;
273             print "@options\n"; # prints "foo bar baz boo"
274              
275             This method does not accept any arguments.
276              
277             =item B
278              
279             Returns an element of the array by its index. You can also use negative index
280             numbers, just as with Perl's core array handling.
281              
282             my $option = $stuff->get(1);
283             print "$option\n"; # prints "bar"
284              
285             If the specified element does not exist, this will return C.
286              
287             This method accepts just one argument.
288              
289             =item B
290              
291             Just like Perl's builtin C.
292              
293             This method does not accept any arguments.
294              
295             =item B
296              
297             Just like Perl's builtin C. Returns the number of elements in the new
298             array.
299              
300             This method accepts any number of arguments.
301              
302             =item B
303              
304             Just like Perl's builtin C.
305              
306             This method does not accept any arguments.
307              
308             =item B
309              
310             Just like Perl's builtin C. Returns the number of elements in the new
311             array.
312              
313             This method accepts any number of arguments.
314              
315             =item B
316              
317             Just like Perl's builtin C. In scalar context, this returns the last
318             element removed, or C if no elements were removed. In list context, this
319             returns all the elements removed from the array, wrapped in a Collection::Array
320             object.
321              
322             This method requires at least one argument.
323              
324             =item B
325              
326             This method returns the first matching item in the array, just like
327             L's C function. The matching is done with a subroutine
328             reference you pass to this method. The subroutine will be called against each
329             element in the array until one matches or all elements have been checked.
330              
331             my $found = $stuff->find_option( sub {/^b/} );
332             print "$found\n"; # prints "bar"
333              
334             This method requires a single argument.
335              
336             =item B
337              
338             This method returns the index of the first matching item in the array, just
339             like L's C function. The matching is done with a
340             subroutine reference you pass to this method. The subroutine will be called
341             against each element in the array until one matches or all elements have been
342             checked.
343              
344             This method requires a single argument.
345              
346             =item B
347              
348             This method returns every element matching a given criteria, just like Perl's
349             core C function. This method requires a subroutine which implements the
350             matching logic. The returned list is provided as a Collection::Array object.
351              
352             my @found = $stuff->grep( sub {/^b/} );
353             print "@found\n"; # prints "bar baz boo"
354              
355             This method requires a single argument.
356              
357             =item B
358              
359             This method transforms every element in the array and returns a new array, just
360             like Perl's core C function. This method requires a subroutine which
361             implements the transformation. The returned list is provided as
362             a Collection::Array object.
363              
364             my @mod_options = $stuff->map( sub { $_ . "-tag" } );
365             print "@mod_options\n"; # prints "foo-tag bar-tag baz-tag boo-tag"
366              
367             This method requires a single argument.
368              
369             =item B
370              
371             This method turns an array into a single value, by passing a function the
372             value so far and the next value in the array, just like L's
373             C function. The reducing is done with a subroutine reference you pass
374             to this method.
375              
376             my $found = $stuff->reduce( sub { $_[0] . $_[1] } );
377             print "$found\n"; # prints "foobarbazboo"
378              
379             This method requires a single argument.
380              
381             =item B
382              
383             =item B
384              
385             Returns the elements of the array in sorted order.
386              
387             You can provide an optional subroutine reference to sort with (as you can with
388             Perl's core C function). However, instead of using C<$a> and C<$b> in
389             this subroutine, you will need to use C<$_[0]> and C<$_[1]>. The returned list
390             is provided as a Collection::Array object.
391              
392             # ascending ASCIIbetical
393             my @sorted = $stuff->sort();
394              
395             # Descending alphabetical order
396             my @sorted_options = $stuff->sort( sub { lc $_[1] cmp lc $_[0] } );
397             print "@sorted_options\n"; # prints "foo boo baz bar"
398              
399             This method accepts a single argument.
400              
401             =item B
402              
403             =item B
404              
405             Sorts the array I, modifying the value of the attribute.
406              
407             You can provide an optional subroutine reference to sort with (as you can with
408             Perl's core C function). However, instead of using C<$a> and C<$b>, you
409             will need to use C<$_[0]> and C<$_[1]> instead. The returned list is provided
410             as a Collection::Array object.
411              
412             This method accepts a single argument.
413              
414             =item B
415              
416             Returns the elements of the array in reversed order. The returned list is
417             provided as a Collection::Array object.
418              
419             This method does not accept any arguments.
420              
421             =item B
422              
423             Returns the elements of the array in random order, like C from
424             L. The returned list is provided as a Collection::Array object.
425              
426             This method does not accept any arguments.
427              
428             =item B
429              
430             Returns the array with all duplicate elements removed, like C from
431             L. The returned list is provided as a Collection::Array object.
432              
433             This method does not accept any arguments.
434              
435             =item B
436              
437             Returns the first C<$count> elements of the array. If C<$count> is greater
438             than the number of elements in the array, the array (without spurious Cs)
439             is returned. Negative C<$count> means "all but the last C<$count> elements". The
440             returned list is provided as a Collection::Array object.
441              
442             =item B
443              
444             Returns the last C<$count> elements of the array. If C<$count> is greater
445             than the number of elements in the array, the array (without spurious Cs)
446             is returned. Negative C<$count> means "all but the first C<$count> elements". The
447             returned list is provided as a Collection::Array object.
448              
449             =item B
450              
451             Joins every element of the array using the separator given as argument, just
452             like Perl's core C function.
453              
454             my $joined = $stuff->join(':');
455             print "$joined\n"; # prints "foo:bar:baz:boo"
456              
457             This method requires a single argument.
458              
459             =item B
460              
461             Prints the output of join($str) to $handle. $handle defaults to STDOUT, and
462             join $str defaults to join()'s default of ','.
463              
464             $joined = $stuff->print(*STDERR, ';'); # prints foo;bar;baz to STDERR
465              
466             =item B
467              
468             Given an index and a value, sets the specified array element's value.
469              
470             This method returns the value at C<$index> after the set.
471              
472             This method requires two arguments.
473              
474             =item B
475              
476             Removes the element at the given index from the array.
477              
478             This method returns the deleted value, either as an array or scalar as
479             dependent on splice context semantics. Note that if no value exists, it will
480              
481             return C.
482              
483             This method requires one argument.
484              
485             =item B
486              
487             Inserts a new element into the array at the given index.
488              
489             This method returns the new value at C<$index>, either as an array or scalar as
490             dependent on splice context semantics.
491              
492             This method requires two arguments.
493              
494             =item B
495              
496             Empties the entire array, like C<@array = ()>.
497              
498             This method does not define a return value.
499              
500             This method does not accept any arguments.
501              
502             =item B
503              
504             =item B
505              
506             This method provides a get/set accessor for the array, based on array indexes.
507             If passed one argument, it returns the value at the specified index. If
508             passed two arguments, it sets the value of the specified index.
509              
510             When called as a setter, this method returns the new value at C<$index>.
511              
512             This method accepts one or two arguments.
513              
514             =item B
515              
516             =item B
517              
518             This method returns an iterator which, on each call, returns C<$n> more items
519             from the array, in order, like C from L. A coderef
520             can optionally be provided; it will be called on each group of C<$n> elements
521             in the array.
522              
523             This method accepts one or two arguments.
524              
525             =item B
526              
527             This method returns a shallow clone of the array reference. The return value
528             is a reference to a new array with the same elements. It is I
529             because any elements that were references in the original will be the I
530             references in the clone.
531              
532             =item B
533              
534             This method returns a list of elements in the array. This method is an alias
535             to the I method.
536              
537             =item B
538              
539             This method returns a flattened list of elements in the array. Will flatten
540             arrays contained within the root array recursively - depth is controlled by the
541             optional $level parameter.
542              
543             =back
544              
545             =head1 SEE ALSO
546              
547             =over 4
548              
549             =item * L
550              
551             =item * L
552              
553             =back
554              
555             =head1 AUTHOR
556              
557             Matthew Phillips
558              
559             =head1 COPYRIGHT AND LICENSE
560              
561             This software is copyright (c) 2020 by Matthew Phillips .
562              
563             This is free software; you can redistribute it and/or modify it under
564             the same terms as the Perl 5 programming language system itself.
565              
566             =cut
567              
568             __END__