File Coverage

blib/lib/Sort/Sub/by_perl_function.pm
Criterion Covered Total %
statement 26 32 81.2
branch 10 16 62.5
condition n/a
subroutine 6 7 85.7
pod 0 2 0.0
total 42 57 73.6


line stmt bran cond sub pod time code
1             package Sort::Sub::by_perl_function;
2              
3             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
4             our $DATE = '2020-02-28'; # DATE
5             our $DIST = 'Sort-Sub'; # DIST
6             our $VERSION = '0.118'; # VERSION
7              
8 1     1   20 use 5.010;
  1         3  
9 1     1   5 use strict;
  1         1  
  1         21  
10 1     1   5 use warnings;
  1         2  
  1         222  
11              
12             sub meta {
13             return {
14 0     0 0 0 v => 1,
15             summary => 'Sort by Perl function',
16             args => {
17             function => {
18             schema => 'perl::funcname*',
19             req => 1,
20             },
21             numeric => {
22             summary => "Compare using Perl's <=> instead of cmp",
23             schema => 'bool*',
24             default => 0,
25             },
26             },
27             };
28             }
29             sub gen_sorter {
30 3     3 0 9 my ($is_reverse, $is_ci, $args) = @_;
31              
32 3         4 my $function = $args->{function};
33 3 50       8 die "Please supply sorter argument 'function'"
34             unless defined $function;
35              
36 3 50       10 if ($function =~ /(.+)::(.+)/) {
37             # qualified with a package name, load associated module
38 0         0 my $mod = $1;
39 0         0 (my $mod_pm = "$mod.pm") =~ s!::!/!g;
40 0         0 require $mod_pm;
41             }
42              
43 3         7 my $code_str = "sub { $function\(\$_[0]) }";
44 3         249 my $code_call_func = eval $code_str;
45 3 50       11 die "Can't compile $code_str: $@" if $@;
46              
47             sub {
48 1     1   8 no strict 'refs';
  1         1  
  1         196  
49              
50 8     8   17 my $caller = caller();
51 8 50       15 my $a = @_ ? $_[0] : ${"$caller\::a"};
  0         0  
52 8 50       14 my $b = @_ ? $_[1] : ${"$caller\::b"};
  0         0  
53              
54 8         155 my $res_a = $code_call_func->($a);
55 8         138 my $res_b = $code_call_func->($b);
56              
57 8 100       28 my $cmp = $args->{numeric} ? $res_a <=> $res_b :
    50          
58             $is_ci ? lc($res_a) cmp lc($res_b) : $res_a cmp $res_b;
59 8 100       29 $is_reverse ? -1*$cmp : $cmp;
60 3         14 };
61             }
62              
63             1;
64             # ABSTRACT: Sort by Perl function
65              
66             __END__