File Coverage

blib/lib/Sort/Hash/Values.pm
Criterion Covered Total %
statement 22 25 88.0
branch 1 2 50.0
condition 1 2 50.0
subroutine 6 7 85.7
pod 1 1 100.0
total 31 37 83.7


line stmt bran cond sub pod time code
1             package Sort::Hash::Values;
2             {
3             $Sort::Hash::Values::VERSION = '0.1.1';
4             }
5 1     1   3215455 use strict;
  1         1  
  1         34  
6 1     1   5 use warnings;
  1         2  
  1         37  
7 1     1   5 use Exporter 5.59 qw/import/;
  1         31  
  1         162  
8             our @EXPORT = our @EXPORT_OK = qw/sort_values/;
9              
10             # Returns keys of sorted hash values
11             sub sort_values(&@) {
12 4     4 1 976 my ($code, %hash) = @_;
13              
14             # Perl has special behavior when code prototype is $$ of uploading
15             # sorted values to @_. || "" is needed to avoid undef warning.
16 4 50 50     26 if ((prototype $code || "") eq '$$') {
17 0         0 my $old_code = $code;
18             $code = sub {
19 0     0   0 $old_code->($a, $b);
20             }
21 0         0 }
22              
23             # I need caller, so the package to modify would be known.
24 4         8 my $pkg = caller;
25              
26             # I need this sub {} because for some reason I'm not allowed to use
27             # lexical pragmas in sort block.
28             my $by_values = sub {
29             # As I'm doing direct symbol table modifications, disable
30             # strict 'refs' for this subroutine.
31 1     1   5 no strict 'refs';
  1         2  
  1         410  
32             # Localize $a and $b in caller package
33 18     18   182 local *{"${pkg}::a"} = \$a->[1];
  18         31  
34 18         19 local *{"${pkg}::b"} = \$b->[1];
  18         25  
35 18         34 $code->();
36 4         17 };
37 4         42 map $_->[0], sort $by_values map [$_ => $hash{$_}], keys %hash;
38             }
39              
40             # Positive value at end
41             1;
42              
43             =head1 NAME
44              
45             Sort::Hash::Values - sort hashes by values
46              
47             =head1 SYNOPSIS
48              
49             use Sort::Hash::Values;
50              
51             my %birth_dates = (
52             Larry => 1954,
53             Randal => 1961,
54             Damian => 1964,
55             Simon => 1978,
56             Mark => 1965,
57             Jesse => 1976,
58             );
59              
60             for my $name (sort_values { $a <=> $b } %birth_dates) {
61             printf "%7s was born in %s.\n", $name, $birth_dates{$name};
62             }
63              
64             =head1 DESCRIPTION
65              
66             C is a function that returns keys of values after
67             sorting its values.
68              
69             =head1 EXPORTS
70              
71             All functions are exported using L. If you don't want this
72             (but why you would use this module then) try importing it using empty
73             list of functions.
74              
75             use Sort::Hash::Values ();
76              
77             =over 4
78              
79             =item sort_values { code } %hash
80              
81             The only function in this module. It sorts every value in hash using
82             specified code and returns list of their keys sorted according to their
83             values.
84              
85             Just like with C in Perl, when code prototype is C<$$>, the
86             variables to sort will be in C<@_> too.
87              
88             =back
89              
90             =head1 CAVEATS
91              
92             When giving the function to C it has to be function in
93             scope where you call C. This is internal limitation caused
94             by the fact that Perl module cannot know what package the function you
95             used belongs. It can only know where C was called. This
96             bug also affects C in L, C in
97             L and other functions that use C<$a> or C<$b>
98             variables - those variables have to be modified in function's package.
99              
100             The code block isn't optional. I really would like to make it optional,
101             but I cannot with Perl limitations. Instead, use C<{ $a cmp $b }> just
102             after C.
103              
104             If you will make C<$a> or C<$b> lexical, except this module to break,
105             as they aren't referencing global variables anymore. This affects every
106             function that uses those variables, even C builtin.
107             L.
108              
109             When using C<$a> or C<$b> only once in the code (with the exception for
110             C builtin), Perl will warn you. This also affects other modules
111             that use those variables. To remove warnings about this, use following
112             code.
113              
114             no warnings 'once';
115              
116             =head1 AUTHOR
117              
118             Konrad Borowski
119              
120             =head1 COPYRIGHT AND LICENSE
121              
122             This software is copyright (c) 2012 by Konrad Borowski.
123              
124             This is free software; you can redistribute it and/or modify it under
125             the same terms as the Perl 5 programming language system itself.