File Coverage

blib/lib/Bubblegum/Object/Array.pm
Criterion Covered Total %
statement 238 238 100.0
branch 45 62 72.5
condition 8 10 80.0
subroutine 63 63 100.0
pod 53 53 100.0
total 407 426 95.5


line stmt bran cond sub pod time code
1             # ABSTRACT: Common Methods for Operating on Array References
2             package Bubblegum::Object::Array;
3              
4 36     36   21599 use 5.10.0;
  36         104  
  36         1419  
5 36     36   155 use namespace::autoclean;
  36         44  
  36         199  
6              
7 36     36   2268 use Bubblegum::Class 'with';
  36         60  
  36         265  
8 36     36   45375 use Bubblegum::Constraints -isas, -types;
  36         173  
  36         576  
9              
10 36     36   175396 use Scalar::Util 'looks_like_number';
  36         74  
  36         144385  
11              
12             with 'Bubblegum::Object::Role::Defined';
13             with 'Bubblegum::Object::Role::Indexed';
14             with 'Bubblegum::Object::Role::List';
15             with 'Bubblegum::Object::Role::Ref';
16             with 'Bubblegum::Object::Role::Coercive';
17             with 'Bubblegum::Object::Role::Output';
18              
19             our @ISA = (); # non-object
20              
21             our $VERSION = '0.45'; # VERSION
22              
23             sub all {
24 2     2 1 2415 my $self = CORE::shift;
25 2         3 my $code = CORE::shift;
26              
27 2 50       24 $code = $code->codify if isa_string $code;
28 2         9 type_coderef $code;
29              
30 2         363 my $found = CORE::grep { $code->($_, @_) } @$self;
  8         138  
31 2 100       15 return $found == @$self ? 1 : 0;
32             }
33              
34             sub any {
35 2     2 1 2674 my $self = CORE::shift;
36 2         6 my $code = CORE::shift;
37              
38 2 50       21 $code = $code->codify if isa_string $code;
39 2         13 type_coderef $code;
40              
41 2         59 my $found = CORE::grep { $code->($_, @_) } @$self;
  8         136  
42 2 100       21 return $found ? 1 : 0;
43             }
44              
45             sub clear {
46 1     1 1 2863 goto ∅
47             }
48              
49             sub count {
50 1     1 1 3117 goto &length;
51             }
52              
53             sub defined {
54 2     2 1 2996 my $self = CORE::shift;
55 2         8 my $index = type_number CORE::shift;
56              
57 2         519 return CORE::defined $self->[$index];
58             }
59              
60             sub delete {
61 1     1 1 3102 my $self = CORE::shift;
62 1         4 my $index = type_number CORE::shift;
63              
64 1         39 return CORE::delete $self->[$index];
65             }
66              
67             sub each {
68 1     1 1 2948 my $self = CORE::shift;
69 1         2 my $code = CORE::shift;
70              
71 1 50       6 $code = $code->codify if isa_string $code;
72 1         5 type_coderef $code;
73              
74 1         31 my $i=0;
75 1         3 foreach my $value (@$self) {
76 7         10 $code->($i, $value, @_); $i++;
  7         26  
77             }
78              
79 1         3 return $self;
80             }
81              
82             sub each_key {
83 1     1 1 3484 my $self = CORE::shift;
84 1         3 my $code = CORE::shift;
85              
86 1 50       5 $code = $code->codify if isa_string $code;
87 1         3 type_coderef $code;
88              
89 1         33 $code->($_, @_) for (0..$#{$self});
  1         6  
90 1         21 return $self;
91             }
92              
93             sub each_n_values {
94 1     1 1 2904 my $self = CORE::shift;
95 1 50       14 my $number = $_[0] ? type_number CORE::shift : 2;
96 1         76 my $code = CORE::shift;
97              
98 1 50       6 $code = $code->codify if isa_string $code;
99 1         3 type_coderef $code;
100              
101 1         32 my @values = @$self;
102              
103 1         11 $code->(CORE::splice(@values, 0, $number), @_) while @values;
104 1         27 return $self;
105             }
106              
107             sub each_value {
108 1     1 1 2940 my $self = CORE::shift;
109 1         3 my $code = CORE::shift;
110              
111 1 50       6 $code = $code->codify if isa_string $code;
112 1         5 type_coderef $code;
113              
114 1         45 $code->($self->[$_], @_) for (0..$#{$self});
  1         8  
115 1         19 return $self;
116             }
117              
118             sub empty {
119 2     2 1 2926 my $self = CORE::shift;
120              
121 2         8 $#$self = -1;
122 2         4 return $self;
123             }
124              
125             sub exists {
126 2     2 1 2784 my $self = CORE::shift;
127 2         7 my $index = type_number CORE::shift;
128 2         80 return CORE::exists $self->[$index];
129             }
130              
131             sub first {
132 1     1 1 2788 my $self = CORE::shift;
133 1         6 return $self->[0];
134             }
135              
136             sub get {
137 2     2 1 2876 my $self = CORE::shift;
138 2         8 my $index = type_number CORE::shift;
139 2         69 return $self->[$index];
140             }
141              
142             sub grep {
143 1     1 1 2831 my $self = CORE::shift;
144 1         2 my $code = CORE::shift;
145              
146 1 50       5 $code = $code->codify if isa_string $code;
147 1         5 type_coderef $code;
148              
149 1         32 return [CORE::grep { $code->($_, @_) } @$self];
  5         14  
150             }
151              
152             sub hashify {
153 1     1 1 2965 my $self = CORE::shift;
154 1         7 my $temp = {};
155              
156 1         4 for (CORE::grep { CORE::defined $_ } @$self) {
  5         6  
157 5         11 $temp->{$_} = 1;
158             }
159              
160 1         7 return $temp;
161             }
162              
163             sub head {
164 1     1 1 2968 my $self = CORE::shift;
165 1         4 return $self->[0];
166             }
167              
168             sub iterator {
169 1     1 1 2797 my $self = CORE::shift;
170              
171 1         2 my $i = 0;
172             return sub {
173 6 100   6   7 return undef if $i > $#{$self};
  6         39  
174 5         12 return $self->[$i++];
175             }
176 1         7 }
177              
178             sub join {
179 2     2 1 3333 my $self = CORE::shift;
180 2 100       10 my $separator = type_string CORE::shift if $_[0];
181 2   100     424 return CORE::join $separator // '', @$self;
182             }
183              
184             sub keyed {
185 1     1 1 2790 my $self = CORE::shift;
186 1         2 my @keys = @_;
187              
188 1         8 type_string $_ for @keys;
189              
190 1         84 my $i=0;
191 1         2 return { CORE::map { $_ => $self->[$i++] } @keys };
  4         11  
192             }
193              
194             sub keys {
195 1     1 1 3022 my $self = CORE::shift;
196 1         3 return [0 .. $#{$self}];
  1         5  
197             }
198              
199             sub last {
200 1     1 1 2956 my $self = CORE::shift;
201 1         5 return $self->[-1];
202             }
203              
204             sub length {
205 4     4 1 2900 my $self = CORE::shift;
206 4         19 return CORE::scalar @$self;
207             }
208              
209             sub list {
210 1     1 1 2901 my $self = CORE::shift;
211 1         4 return (@$self);
212             }
213              
214             sub map {
215 1     1 1 3384 my $self = CORE::shift;
216 1         2 my $code = CORE::shift;
217              
218 1 50       7 $code = $code->codify if isa_string $code;
219 1         5 type_coderef $code;
220              
221 1         37 return [CORE::map { $code->($_, @_) } @$self];
  5         17  
222             }
223              
224             sub max {
225 1     1 1 3201 my $self = CORE::shift;
226 1         3 my $max;
227              
228 1         2 for my $val (@$self) {
229 10 100       16 next if CORE::ref($val);
230 8 100       13 next if ! CORE::defined($val);
231 7 50       15 next if ! looks_like_number($val);
232 7   66     14 $max //= $val;
233 7 100       12 $max = $val if $val > $max;
234             }
235              
236 1         6 return $max;
237             }
238              
239             sub min {
240 2     2 1 2892 my $self = CORE::shift;
241 2         3 my $min;
242              
243 2         5 for my $val (@$self) {
244 20 100       33 next if CORE::ref($val);
245 16 100       24 next if ! CORE::defined($val);
246 11 50       21 next if ! looks_like_number($val);
247 11   66     20 $min //= $val;
248 11 100       57 $min = $val if $val < $min;
249             }
250              
251 2         11 return $min;
252             }
253              
254             sub none {
255 2     2 1 2833 my $self = CORE::shift;
256 2         4 my $code = CORE::shift;
257              
258 2 50       24 $code = $code->codify if isa_string $code;
259 2         11 type_coderef $code;
260              
261 2         60 my $found = CORE::grep { $code->($_, @_) } @$self;
  8         137  
262 2 100       23 return $found ? 0 : 1;
263             }
264              
265             sub nsort {
266 1     1 1 3172 my $self = CORE::shift;
267 1     5   5 my $code = sub { $a <=> $b };
  5         13  
268 1         15 return $self->sort($code);
269             }
270              
271             sub one {
272 27     27 1 3077 my $self = CORE::shift;
273 27         47 my $code = CORE::shift;
274              
275 27 50       297 $code = $code->codify if isa_string $code;
276 27         157 type_coderef $code;
277              
278 27         1136 my $found = CORE::grep { $code->($_, @_) } @$self;
  74         1380  
279 27 100       301 return $found == 1 ? 1 : 0;
280             }
281              
282             sub pairs {
283 2     2 1 7209 goto &pairs_array;
284             }
285              
286             sub pairs_array {
287 2     2 1 4 my $self = CORE::shift;
288 2         4 my $i=0;
289 2         28 return [CORE::map +[$i++, $_], @$self];
290             }
291              
292             sub pairs_hash {
293 1     1 1 3918 my $self = CORE::shift;
294 1         3 my $i=0;
295 1         2 return {CORE::map {$i++ => $_} @$self};
  5         15  
296             }
297              
298             sub part {
299 1     1 1 3263 my $self = CORE::shift;
300 1         4 my $code = CORE::shift;
301              
302 1 50       7 $code = $code->codify if isa_string $code;
303 1         5 type_coderef $code;
304              
305 1         47 my $result = [[],[]];
306 1         5 foreach my $value (@$self) {
307 10 100       21 my $slot = $code->($value, @_) ? $$result[0] : $$result[1];
308 10         49 CORE::push @$slot, $value;
309             }
310              
311 1         9 return $result;
312             }
313              
314             sub pop {
315 6     6 1 3497 my $self = CORE::shift;
316 6         23 return CORE::pop @$self;
317             }
318              
319             sub print {
320 2     2 1 2966 my $self = CORE::shift;
321 2         10 return CORE::print @$self, @_;
322             }
323              
324             sub push {
325 1     1 1 3036 my $self = CORE::shift;
326 1         2 my @args = @_;
327              
328 1         4 CORE::push @$self, @args;
329 1         6 return $self;
330             }
331              
332             sub random {
333 10     10 1 5727 my $self = CORE::shift;
334 10         13 return @$self[rand(1+$#{$self})];
  10         109  
335             }
336              
337             sub reverse {
338 1     1 1 2972 my $self = CORE::shift;
339 1         7 return [CORE::reverse @$self];
340             }
341              
342             sub rotate {
343 3     3 1 3195 my $self = CORE::shift;
344 3         6 CORE::push @$self, CORE::shift @$self;
345 3         16 return $self;
346             }
347              
348             sub rnsort {
349 1     1 1 3214 my $self = CORE::shift;
350 1     8   5 my $code = sub { $b <=> $a };
  8         15  
351 1         8 return $self->sort($code);
352             }
353              
354             sub rsort {
355 1     1 1 3183 my $self = CORE::shift;
356 1     4   5 my $code = sub { $b cmp $a };
  4         13  
357 1         4 return $self->sort($code);
358             }
359              
360             sub say {
361 2     2 1 3182 my $self = CORE::shift;
362 2         155 return print(@$self, @_, "\n");
363             }
364              
365             sub set {
366 1     1 1 3122 my $self = CORE::shift;
367 1         5 my $index = type_number CORE::shift;
368 1         42 return $self->[$index] = CORE::shift;
369             }
370              
371             sub shift {
372 5     5 1 3220 my $self = CORE::shift;
373 5         19 return CORE::shift @$self;
374             }
375              
376             sub size {
377 1     1 1 3174 goto &length;
378             }
379              
380             sub slice {
381 1     1 1 3084 my $self = CORE::shift;
382 1         3 my @indicies = @_;
383              
384 1         6 type_number $_ for @indicies;
385              
386 1         56 return [@$self[@indicies]];
387             }
388              
389             sub sort {
390 4     4 1 3296 my $self = CORE::shift;
391 4 100       20 my $code = type_coderef CORE::shift if $_[0];
392 4   100 4   106 $code ||= sub { $a cmp $b };
  4         10  
393 4         16 return [CORE::sort { $code->($a, $b) } @$self];
  21         23  
394             }
395              
396             sub sum {
397 1     1 1 3174 my $self = CORE::shift;
398 1         2 my $sum = 0;
399              
400 1         4 for my $val (@$self) {
401 5 50       8 next if CORE::ref($val);
402 5 50       10 next if !CORE::defined($val);
403 5 50       11 next if !looks_like_number($val);
404 5         6 $sum += $val;
405             }
406              
407 1         5 return $sum;
408             }
409              
410             sub tail {
411 1     1 1 3089 my $self = CORE::shift;
412 1         9 return [@$self[1 .. $#$self]];
413             }
414              
415             sub unique {
416 1     1 1 3202 my $self = CORE::shift;
417              
418 1         2 my %seen;
419 1         2 return [CORE::grep { not $seen{$_}++ } @$self];
  7         17  
420             }
421              
422             sub unshift {
423 1     1 1 3202 my $self = CORE::shift;
424 1         3 my @args = @_;
425              
426 1         3 CORE::unshift @$self, @args;
427 1         5 return $self;
428             }
429              
430             sub values {
431 1     1 1 3283 my $self = CORE::shift;
432 1         7 return [@$self];
433             }
434              
435             1;
436              
437             __END__