File Coverage

blib/lib/Template/Plugin/ListUtil.pm
Criterion Covered Total %
statement 73 79 92.4
branch 6 6 100.0
condition 12 16 75.0
subroutine 24 26 92.3
pod 22 22 100.0
total 137 149 91.9


line stmt bran cond sub pod time code
1             package Template::Plugin::ListUtil;
2              
3 2     2   188837 use List::Util;
  2         5  
  2         148  
4 2     2   1890 use Template::Plugin::Procedural;
  2         2884  
  2         68  
5 2     2   27 use vars qw(@ISA $VERSION);
  2         4  
  2         2098  
6              
7             $VERSION = "0.02";
8             @ISA = qw(Template::Plugin::Procedural);
9              
10             =head1 NAME
11              
12             Template::Plugin::ListUtil - List::Util functions for TT
13              
14             =head1 SYNOPSIS
15              
16             [% mylist = [ 1, 2, 3, 4, 4, 3, 2, 5, 2 ] %]
17              
18             [% USE ListUtil %]
19             The largest value in our array is [% ListUtil.largest(mylist) %]
20              
21             [% USE ListUtilVMethods %]
22             The largest value in our array is [% mylist.largest %]
23              
24             =head1 DESCRIPTION
25              
26             This module provides a selection of handy functions for dealing with
27             lists in the Template Toolkit. Most of the functions are adapted
28             from those provided by or documented in L, though note
29             these have been altered in name and function to work better with
30             the template toolkit.
31              
32             To access the functions like class methods, simply use the plugin
33             from within a Template Toolkit template:
34              
35             [% USE ListUtil %]
36              
37             And then call the method against the ListUtil object.
38              
39             [% max = ListUtil.largest(mylist) %]
40              
41             Alternatively you can load the functions as vmethods:
42              
43             [% USE ListUtilVMethods %]
44             [% max = mylist.largest %]
45              
46             Using the VMethods plugin as above will cause the vmethods to be in
47             effect for the current template and all templates called from that
48             template. To allow all templates called from any instance of the
49             Template module load the module from Perl with the 'install'
50             parameter.
51              
52             use Template::Plugin::ListUtilVMethods 'install';
53              
54             =head1 FUNCTIONS PROVIDED
55              
56             These are the functions that you can use once you've loaded the
57             plugin.
58              
59             =head2 Finding the largest/smallest
60              
61             =over
62              
63             =item largest
64              
65             Return the numerically largest value of the list.
66              
67             =cut
68              
69 2     2 1 94407 sub largest { List::Util::max(@{ $_[0] }) }
  2         35  
70              
71             =item largeststr
72              
73             Return the largest value of the list, sorted by unicode value
74              
75             =cut
76              
77 2     2 1 23035 sub largeststr { List::Util::maxstr(@{ $_[0] }) }
  2         23  
78              
79             =item smallest
80              
81             Return the numerically smallest value of the list
82              
83             =cut
84              
85 2     2 1 24653 sub smallest { List::Util::min(@{ $_[0] }) }
  2         26  
86              
87             =item smalleststr
88              
89             Return the smallest value of the list, sorted by unicode value
90              
91             =cut
92              
93 2     2 1 32521 sub smalleststr { List::Util::minstr(@{ $_[0] }) }
  2         24  
94              
95             =back
96              
97             =head2 Simple Statistics
98              
99             =over
100              
101             =item total
102              
103             The sum of adding up all the elements in the list
104              
105             =cut
106              
107 48     48 1 90 sub total { List::Util::reduce { $a + $b } @{ $_[0] } }
  4     4   22937  
  4         55  
108              
109             =item even
110              
111             Returns true if and only if this list contains an even number
112             of items, or the list is empty.
113              
114             =cut
115              
116 12     12 1 95828 sub even { int(@{ $_[0] } / 2) == (@{ $_[0] } / 2) }
  12         40  
  12         88  
117              
118             =item odd
119              
120             Returns true if and only if this list contains an odd number
121             of items.
122              
123             =cut
124              
125 8     8 1 107437 sub odd { int(@{ $_[0] } / 2) != (@{ $_[0] } / 2) }
  8         34  
  8         40  
126              
127             =item mean
128              
129             The mathematical mean (numerical average) of the list
130              
131             =cut
132              
133 2     2 1 24135 sub mean { total($_[0]) / @{ $_[0] } }
  2         34  
134              
135             =item mode
136              
137             Mode returns a list of the most frequently occurring elements
138             in a list. For example, for the list:
139              
140             ["buffy", "buffy", "willow", "willow", "buffy" ]
141              
142             The list
143              
144             ["buffy"]
145              
146             Would be returned because "Buffy" occurs more times in the list
147             than any other element. However, for some lists have more than
148             one element that could be consider the most frequent:
149              
150             [ 1, 2, 3, 3, 2, 2, 3, 4, 5, 5 ]
151              
152             In which case C returns them all:
153              
154             [ 2, 3 ]
155              
156             You can use the virtual method C on the resulting list from
157             C to pick an arbitrary value, or the C function (see above)
158             to to take an average of the values.
159              
160             =cut
161              
162             sub mode
163             {
164 4     4 1 50789 my %hash;
165 4         10 $hash{ $_ }++ foreach (@{ $_[0] });
  4         69  
166              
167 4         11 my $list = [];
168 4         13 my $value = (values %hash)[0];
169 4         12 foreach my $key (keys %hash)
170             {
171 20 100       68 if ($hash{ $key } eq $value)
    100          
172 8         9 { push @{$list}, $key }
  8         19  
173             elsif ($hash{ $key } > $value )
174 2         6 { $list = [ $key ]; $value = $hash{ $key }}
  2         16  
175             }
176              
177 4         47 return $list;
178             }
179              
180             =item median
181              
182             Returns a list containing either the middle element of the list (if
183             the list is odd in length) or the middle two elements of the list (if
184             the list is even in length.) To get a mathematical median you should
185             presort the list (probably with the C virtual method) before
186             you pass it to C. Like with C you can use the virtual
187             method C on the resulting list from C to pick an
188             arbitrary value, or the C function (see above) to to take an
189             average of the values.
190              
191             =cut
192              
193             sub median
194             {
195 4     4 1 44394 my $list = shift;
196 4         8 my $mid = int(@{ $list } / 2);
  4         16  
197              
198 4 100       16 ( even($list) ) ? [ $list->[ $mid - 1], $list->[ $mid ] ]
199             : [ $list->[ $mid ] ]
200             }
201              
202             =back
203              
204             =head2 Randomisation Functions
205              
206             =over
207              
208             =item shuffle
209              
210             Return a new list made up from randomly shuffled elements of the
211             list passed.
212              
213             =cut
214              
215 2     2 1 23961 sub shuffle { [ List::Util::shuffle(@{ $_[0] }) ] }
  2         212  
216              
217             =item random
218              
219             Return a random item from the passed list.
220              
221             =cut
222              
223 6     6 1 142866 sub random { (@{ $_[0] })[rand(@{ $_[0] })] }
  6         38  
  6         27  
224              
225             =back
226              
227             =head2 Truth Functions
228              
229             =over
230              
231             =item anytrue / anyfalse
232              
233             Is at least one item in the list true / false?
234              
235             =cut
236              
237             # this function copyright Graham Barr
238 0   0 0 1 0 sub anytrue { $_ && return 1 for @{ $_[0] }; 0 }
  0         0  
  0         0  
239              
240 0   0 0 1 0 sub anyfalse { $_ || return 1 for @{ $_[0] }; 0 }
  0         0  
  0         0  
241              
242             =item alltrue / allfalse
243              
244             Are all items (i.e. every single item) in the list true / false?
245              
246             =cut
247              
248             # this function copyright Graham Barr
249 8   100 8 1 165396 sub alltrue { $_ || return 0 for @{ $_[0] } ; 1 }
  8         81  
  2         9  
250              
251 8   100 8 1 119203 sub allfalse { $_ && return 0 for @{ $_[0] } ; 1 }
  8         75  
  2         9  
252              
253             =item nonetrue / nonefalse
254              
255             Is no element in the list true / false?
256              
257             =cut
258              
259             # this function copyright Graham Barr
260 8   100 8 1 143866 sub nonetrue { $_ && return 0 for @{ $_[0] } ; 1 }
  8         84  
  2         10  
261              
262 8   100 8 1 122957 sub nonefalse { $_ || return 0 for @{ $_[0] } ; 1 }
  8         76  
  2         9  
263              
264             =item notalltrue / notallfalse
265              
266             Is at least one element in the list false?
267              
268             =cut
269              
270             # this function copyright Graham Barr
271 8   100 8 1 122269 sub notalltrue { $_ || return 1 for @{ $_[0] } ; 0 }
  8         79  
  2         9  
272              
273 8   100 8 1 115431 sub notallfalse { $_ && return 1 for @{ $_[0] } ; 0 }
  8         79  
  2         9  
274              
275             =item true
276              
277             How many items are true?
278              
279             =cut
280              
281             # this function copyright Graham Barr
282 8     8 1 130034 sub true { scalar grep { $_ } @{ $_[0] } }
  24         97  
  8         34  
283              
284             =item false
285              
286             How many items are false?
287              
288             =cut
289              
290             # this function copyright Graham Barr
291 8     8 1 134598 sub false { scalar grep { !$_ } @{ $_[0] } }
  24         82  
  8         27  
292              
293             =back
294              
295             =head1 AUTHOR
296              
297             Written by Mark Fowler Emark@twoshortplanks.comE
298              
299             Uses the List::Util module, by Graham Barr .
300              
301             Except as indicated in comments in the code, Copyright Mark Fowler
302             2003; All Rights Reserved. As indicated by comments in code some code
303             Copyright Graham Barr (1997-2001).
304              
305             This program is free software; you can redistribute it
306             and/or modify it under the same terms as Perl itself.
307              
308             =head1 BUGS
309              
310             None known.
311              
312             Bugs should be reported to me via the CPAN RT system.
313             L.
314              
315             =head1 SEE ALSO
316              
317             L (for doing this in Perl)
318              
319             L (details on how the vmethods are installed)
320              
321             =cut
322              
323             1;