File Coverage

blib/lib/Sort/ArrayOfArrays.pm
Criterion Covered Total %
statement 75 104 72.1
branch 32 72 44.4
condition 14 38 36.8
subroutine 7 7 100.0
pod 0 4 0.0
total 128 225 56.8


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             package Sort::ArrayOfArrays;
4              
5 6     6   79017 use strict;
  6         15  
  6         267  
6 6     6   34 use Exporter;
  6         13  
  6         281  
7 6     6   33 use vars qw(@ISA @EXPORT_OK $VERSION);
  6         16  
  6         17435  
8             @ISA = qw(Exporter);
9             @EXPORT_OK = qw(sort_it);
10             $VERSION = '1.00';
11              
12             sub new {
13 5     5 0 112 my $type = shift;
14 5 50       83 my @PASSED_ARGS = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
  5         25  
15 5         28 my @DEFAULT_ARGS = (
16             header_row => 0,
17             results => [],
18             sort_column => '',
19             sort_code => [],
20             );
21 5         96 my %ARGS = (@DEFAULT_ARGS, @PASSED_ARGS);
22 5         20 my $self = bless \%ARGS, $type;
23 5         26 return $self;
24             }
25              
26             sub sort_it {
27 5     5 0 34 my $self = shift;
28              
29 5 50       25 unless(ref $self eq __PACKAGE__) {
30 0         0 $self = __PACKAGE__->new({
31             results => $self,
32             sort_column => $_[0],
33             sort_code => $_[1],
34             header_row => $_[2],
35             });
36             }
37              
38 5 50       53 die "\$self->{results} is required" unless($self->{results});
39 5 50 33     93 die "\$self->{results} needs to be an array of arrays" unless(ref $self->{results} eq 'ARRAY' && $self->{results}->[0] && ref $self->{results}->[0] eq 'ARRAY');
      33        
40 5 50       23 if($self->{header_row}) {
41 0         0 $self->{zero_row} = shift @{$self->{results}};
  0         0  
42             }
43              
44 5         11 $self->{rows} = (@{$self->{results}} - 1);
  5         17  
45              
46 5         64 $self->make_sort_code_ref;
47              
48 5         12 my $sort_method = $self->{sort_code_ref};
49 5         25 my @temp = (0 .. $self->{rows});
50 5         215 @temp = sort $sort_method @temp;
51              
52 5         16 my $return = [];
53              
54 5         25 for(my $i=0;$i<@temp;$i++) {
55 15         54 $return->[$i] = $self->{results}->[$temp[$i]];
56             }
57              
58 5 50       23 if($self->{header_row}) {
59 0         0 unshift @{$return}, $self->{zero_row};
  0         0  
60 0         0 delete $self->{zero_row};
61             }
62 5         13 $self->{results} = $return;
63 5         22 return $return;
64             }
65              
66             sub make_sort_code_text {
67 5     5 0 10 my $self = shift;
68 5 50       23 return if($self->{sort_code_text});
69              
70 5         11 my $total_sorts = 0;
71 5         32 foreach my $this_sort_column (split /\s*,\s*/, $self->{sort_column}) {
72 7         14 $total_sorts++;
73 7         20 my $col = abs($this_sort_column);
74 7 50 33     54 if($self->{sort_code} && ref $self->{sort_code}) {
75 7 50 33     90 if(ref $self->{sort_code} eq 'HASH' && $self->{sort_code}->{$col}) {
    50 33        
76 0 0       0 if(ref $self->{sort_code}->{$col}) {
77 0 0       0 die "any ref for \$self->{sort_code}->{$col} needs to be an CODE ref" unless(ref $self->{sort_code}->{$col} eq 'CODE');
78 0         0 $self->{sort_code_ref} = $self->{sort_code}->{$col};
79 0         0 return;
80             }
81             } elsif(ref $self->{sort_code} eq 'ARRAY' && $self->{sort_code}->[$col]) {
82 0 0       0 if(ref $self->{sort_code}->[$col]) {
83 0 0       0 die "any ref for \$self->{sort_code}->[$col] needs to be an CODE ref" unless(ref $self->{sort_code}->[$col] eq 'CODE');
84 0         0 $self->{sort_code_ref} = $self->{sort_code}->[$col];
85 0         0 return;
86             }
87             }
88             }
89             }
90              
91 5         20 $self->{sort_code_text} = "sub {\n";#"}"
92 5         15 my $this_sort = 0;
93 5         24 foreach my $this_sort_column (split /\s*,\s*/, $self->{sort_column}) {
94 7         15 $this_sort++;
95 7         22 my $this_sort_method;
96 7 50 33     103 if($self->{sort_code} && ref $self->{sort_code}) {
97 7 50 33     1237 if(ref $self->{sort_code} eq 'HASH' && $self->{sort_code}->{$this_sort_column}) {
    50 33        
98 0         0 $this_sort_method = $self->{sort_code}->{$this_sort_column};
99             } elsif(ref $self->{sort_code} eq 'ARRAY' && $self->{sort_code}->[$this_sort_column]) {
100 0         0 $this_sort_method = $self->{sort_code}->[$this_sort_column];
101             }
102             }
103 7         45 my $this_toggle = $this_sort_column =~ s/^\-(\d+)$/$1/;
104              
105 7 50       47 unless($this_sort_method) {
106 7         15 $this_sort_method = 'aa';
107 7         30 for(my $i=0;$i<=$self->{rows};$i++) {
108 7 100       54 if($self->{results}->[$i]->[$this_sort_column] =~ /[^0-9.\-+ ]/) {
    50          
109 6         13 last;
110             } elsif($self->{results}->[$i]->[$this_sort_column] =~ /^[0-9.\-+]+$/) {
111 1 50       5 next if($self->{results}->[$i]->[$this_sort_column] =~ /^\.+$/);
112 1         2 $this_sort_method = 'na';
113 1         2 last;
114             }
115             }
116             }
117              
118 7 100       32 if($total_sorts == $this_sort) {
119 5 100 66     86 if($this_toggle && $this_sort_method =~ /^.a$/) {
    50 33        
120 4         124 $this_sort_method =~ s/^(.)a$/$1d/i;
121             } elsif($this_toggle && $this_sort_method =~ /^.d$/) {
122 0         0 $this_sort_method =~ s/^(.)d$/$1a/i;
123             }
124             }
125              
126             # I just change stuff of type link to stuff of type regex, with the regex below
127 7 50       45 if ($this_sort_method =~ s/^l(.)$/r$1/i) {
128 0 0       0 die "need regex for sort_method on column $this_sort_column" unless(exists $self->{sort_method_regex}->{$this_sort_column});
129 0         0 $self->{sort_method_regex}->{$this_sort_column} = qr@]+?>(.+?)@i;
130             }
131              
132 7         34 my $symbol;
133 7         15 my $special_sort_method = 0;
134 7 100       286 if($this_sort_method =~ /^a.$/i) {
    50          
    0          
    0          
135 6         19 $symbol = 'cmp';
136             } elsif ($this_sort_method =~ /^n.$/i) {
137 1         3 $symbol = '<=>';
138             } elsif ($this_sort_method =~ /^t.$/i) {
139 0         0 $special_sort_method = 1;
140             } elsif ($this_sort_method =~ /^r.$/i) {
141 0 0       0 die "need regex for sort_method on column $this_sort_column" unless($self->{sort_method_regex}->{$this_sort_column});
142 0   0     0 $symbol = $self->{sort_method_symbol}->{$this_sort_column} || 'cmp';
143 0         0 $self->{sort_code_text} .= <
144             my (\$_a) = \$self->{results}->[\$a]->[$this_sort_column] =~ /$self->{sort_method_regex}->{$this_sort_column}/;
145             my (\$_b) = \$self->{results}->[\$b]->[$this_sort_column] =~ /$self->{sort_method_regex}->{$this_sort_column}/;
146             SORT_METHOD
147              
148 0 0       0 if($self->{sort_code}->[$this_sort_column] =~ /^.d$/i) {
149 0         0 $self->{sort_code_text} = "{\n $self->{sort_code_text}\n \$_b $symbol \$_a\n}";
150             } else {
151 0         0 $self->{sort_code_text} = "{\n $self->{sort_code_text}\n \$_a $symbol \$_b\n}";
152             }
153 0         0 $special_sort_method = 1;
154             } else {
155 0         0 die "unknown sort method $this_sort_method";
156             }
157              
158 7 100 66     99 if(!$special_sort_method && $this_sort_method =~ /^.a$/i) {
    50          
159 3         20 $self->{sort_code_text} .= ' $self->{results}->[$a]->[' . "$this_sort_column" .'] ' . "$symbol" . ' $self->{results}->[$b]->[' . "$this_sort_column" . "] ||\n";
160             } elsif ($this_sort_method =~ /^.d$/i) {
161 4         37 $self->{sort_code_text} .= ' $self->{results}->[$b]->[' . "$this_sort_column" .'] ' . "$symbol" . ' $self->{results}->[$a]->[' . "$this_sort_column" . "] ||\n";
162             }
163             }
164             # sadly, this line is to unbug vi {
165 5         67 $self->{sort_code_text} =~ s/\s*\|\|\s*$/\n\}/;
166             }
167              
168             sub make_sort_code_ref {
169 5     5 0 12 my $self = shift;
170 5 50 33     29 return if($self->{sort_code_ref} && ref $self->{sort_code_ref} eq 'CODE');
171 5         20 $self->make_sort_code_text;
172 5         1348 $self->{sort_code_ref} = eval $self->{sort_code_text};
173 5 50       27 if($@) {
174 0           die "$self->{sort_code_text}\ndid not lead to a valid CODE ref";
175             }
176             }
177              
178             1;
179              
180             __END__