File Coverage

blib/lib/Sort/Sub/by_perl_function.pm
Criterion Covered Total %
statement 28 32 87.5
branch 10 16 62.5
condition n/a
subroutine 6 7 85.7
pod 0 2 0.0
total 44 57 77.1


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.117'; # VERSION
7              
8 1     1   19 use 5.010;
  1         4  
9 1     1   5 use strict;
  1         2  
  1         19  
10 1     1   4 use warnings;
  1         2  
  1         227  
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 7 my ($is_reverse, $is_ci, $args) = @_;
31              
32 3         6 my $function = $args->{function};
33 3 50       8 die "Please supply sorter argument 'function'"
34             unless defined $function;
35              
36 3 50       8 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         234 my $code_call_func = eval $code_str;
45 3 50       10 die "Can't compile $code_str: $@" if $@;
46              
47             sub {
48 1     1   8 no strict 'refs';
  1         2  
  1         197  
49              
50 8     8   16 my $caller = caller();
51 8 50       16 my $a = @_ ? $_[0] : ${"$caller\::a"};
  8         21  
52 8 50       15 my $b = @_ ? $_[1] : ${"$caller\::b"};
  8         18  
53              
54 8         163 my $res_a = $code_call_func->($a);
55 8         146 my $res_b = $code_call_func->($b);
56              
57 8 100       27 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       31 $is_reverse ? -1*$cmp : $cmp;
60 3         16 };
61             }
62              
63             1;
64             # ABSTRACT: Sort by Perl function
65              
66             __END__
67              
68             =pod
69              
70             =encoding UTF-8
71              
72             =head1 NAME
73              
74             Sort::Sub::by_perl_function - Sort by Perl function
75              
76             =head1 VERSION
77              
78             This document describes version 0.117 of Sort::Sub::by_perl_function (from Perl distribution Sort-Sub), released on 2020-02-28.
79              
80             =head1 SYNOPSIS
81              
82             Generate sorter (accessed as variable) via L<Sort::Sub> import:
83              
84             use Sort::Sub '$by_perl_function'; # use '$by_perl_function<i>' for case-insensitive sorting, '$by_perl_function<r>' for reverse sorting
85             my @sorted = sort $by_perl_function ('item', ...);
86              
87             Generate sorter (accessed as subroutine):
88              
89             use Sort::Sub 'by_perl_function<ir>';
90             my @sorted = sort {by_perl_function} ('item', ...);
91              
92             Generate directly without Sort::Sub:
93              
94             use Sort::Sub::by_perl_function;
95             my $sorter = Sort::Sub::by_perl_function::gen_sorter(
96             ci => 1, # default 0, set 1 to sort case-insensitively
97             reverse => 1, # default 0, set 1 to sort in reverse order
98             );
99             my @sorted = sort $sorter ('item', ...);
100              
101             Use in shell/CLI with L<sortsub> (from L<App::sortsub>):
102              
103             % some-cmd | sortsub by_perl_function
104             % some-cmd | sortsub by_perl_function --ignore-case -r
105              
106             =head1 DESCRIPTION
107              
108             This:
109              
110             use Sort::Sub '$by_perl_function', {function=>'length'};
111             my @sorted = sort $by_perl_function @data;
112              
113             is equivalent to:
114              
115             my @sorted = sort { length($a) <=> length($b) } @data;
116              
117             =for Pod::Coverage ^(gen_sorter|meta)$
118              
119             =head1 SORT ARGUMENTS
120              
121             C<*> marks required arguments.
122              
123             =head2 function*
124              
125             perl::funcname.
126              
127             =head2 numeric
128              
129             bool.
130              
131             Compare using Perl's <=E<gt> instead of cmp.
132              
133             =head1 HOMEPAGE
134              
135             Please visit the project's homepage at L<https://metacpan.org/release/Sort-Sub>.
136              
137             =head1 SOURCE
138              
139             Source repository is at L<https://github.com/perlancar/perl-Sort-Sub>.
140              
141             =head1 BUGS
142              
143             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Sort-Sub>
144              
145             When submitting a bug or request, please include a test-file or a
146             patch to an existing test-file that illustrates the bug or desired
147             feature.
148              
149             =head1 SEE ALSO
150              
151             L<Sort::Sub>
152              
153             =head1 AUTHOR
154              
155             perlancar <perlancar@cpan.org>
156              
157             =head1 COPYRIGHT AND LICENSE
158              
159             This software is copyright (c) 2020, 2019, 2018, 2016, 2015 by perlancar@cpan.org.
160              
161             This is free software; you can redistribute it and/or modify it under
162             the same terms as the Perl 5 programming language system itself.
163              
164             =cut