File Coverage

blib/lib/Acme/List/CarCdr.pm
Criterion Covered Total %
statement 46 47 97.8
branch 14 16 87.5
condition 5 5 100.0
subroutine 6 6 100.0
pod n/a
total 71 74 95.9


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             #
3             # c[ad]+r list-operation support for Perl, based on (car) and (cdr) and
4             # so forth of lisp fame, though with a limit of 704 as to the maximum
5             # length any such shenanigans.
6             #
7             # Run perldoc(1) on this file for additional documentation.
8              
9             package Acme::List::CarCdr;
10              
11 2     2   40247 use 5.010000;
  2         6  
  2         69  
12 2     2   8 use strict;
  2         5  
  2         89  
13 2     2   10 use warnings;
  2         6  
  2         67  
14              
15 2     2   7 use Carp qw(croak);
  2         3  
  2         122  
16 2     2   1053 use Moo;
  2         34685  
  2         11  
17              
18             our $VERSION = '0.01';
19              
20             ##############################################################################
21             #
22             # METHODS
23              
24             sub AUTOLOAD {
25 8     8   2646 my $method = our $AUTOLOAD;
26 8 100       48 if ( $method =~ m/::c([ad]{1,704})r$/ ) {
27 7         15 my $ops = reverse $1;
28 7         6 my $self = shift;
29 7         9 my $ref = \@_;
30 7         9 my $start = 0;
31 7         6 my $end;
32 7         7 my $delve = 0;
33 7         28 while ( $ops =~ m/\G([ad])(\1*)/cg ) {
34 11         12 my $op = $1;
35 11   100     35 my $len = length $2 || 0;
36 11 100       15 if ( $op eq 'a' ) {
37 5 100       10 if ( $len > 0 ) {
38 2         4 for my $i ( 1 .. $len ) {
39 2 100       6 if ( ref $ref->[$start] ne 'ARRAY' ) {
40 1         24 croak "$method: " . $ref->[$start] . " is not a list";
41             }
42 1         2 $ref = $ref->[$start];
43 1         2 $start = 0;
44             }
45             }
46 4         9 $end = $start;
47 4         14 $delve = 1;
48             } else { # $op eq 'd'
49 6 100       12 if ($delve) {
50 1 50       4 if ( ref $ref->[$start] ne 'ARRAY' ) {
51 0         0 croak "$AUTOLOAD: " . $ref->[$start] . " is not a list";
52             }
53 1         2 $ref = $ref->[$start];
54 1         1 $start = 0;
55             }
56 6         7 $start += $len + 1;
57 6         18 $end = $#$ref;
58             }
59             }
60 6 50       9 return if $start > $end;
61 6 100 100     22 return @{ $ref->[$start] }
  1         5  
62             if ( $start == $end and ref $ref->[$start] eq 'ARRAY' );
63 5         30 return @$ref[ $start .. $end ];
64             } else {
65 1         11 croak "no such method $method";
66             }
67             }
68              
69             1;
70             __END__