in reply to Coming up with good examples in POD
G'day Lady Aleena,
"I just can not come up with a list where this might be needed on alphabetical strings."
With split_sort(), as currently written, I can't see any use for the alpha sort type:
it will return the same as a plain sort (in all cases, as far as I can tell).
With an alpha sort type ignoring case, you could get this difference:
$ perl E 'my @x = ("ade:Y", "Abc:X", "Afg:Z"); say for sort @x'
Abc:X
Afg:Z
ade:Y
$ perl E 'my @x = ("ade:Y", "Abc:X", "Afg:Z"); say for sort { fc($a)
+cmp fc($b) } @x'
Abc:X
ade:Y
Afg:Z
With an alpha sort type expecting Unicode, you could get this difference:
$ perl C E 'my @x = ("\x{c5}de:Y", "Abc:X", "Afg:Z"); say for sort @
+x'
Abc:X
Afg:Z
Åde:Y
$ perl MUnicode::Collate C E 'my @x = ("\x{c5}de:Y", "Abc:X", "Afg:
+Z"); say for Unicode::Collate>new>sort(@x)'
Abc:X
Åde:Y
Afg:Z
"I am now thinking that I should just put a note in saying that the alphabetical usage is redundant."
Perhaps not entirely redundant.
Consider its potential use in a scenario where you process an AoA
which holds a mixture of numeric and alphabetic arrays.
my @multi_sorts = (
[ $array1, ':', 'num' ],
[ $array2, '', 'alpha' ],
[ $array3, ',', 'num' ],
);
handle_multi_mixed_sorts(\@multi_sorts);
# At this point in the code, each of the arrays in @multi_sorts
# has the original array still as the first element
# and the sorted array now as the fourth element.
sub handle_multi_mixed_sorts {
my ($multi_sorts) = @_;
for my $i (0 .. $#$multi_sorts) {
push @{$multi_sorts>[$i]}, [
sort { split_sort($a, $b,
$multi_sorts>[$i][1], $multi_sorts>[$i][2])
} @{$multi_sorts>[$i][0]}
];
}
return;
}
Do note that I just typed that code directly into my post:
it's entirely untested.
Re^2: Coming up with good examples in POD
by Lady_Aleena (Curate) on Jul 28, 2020 at 07:12 UTC

Case sensitivity is outside the scope of split_sort, and should a user want to add case insensitivity to the use of split_sort, they can do something like the following.
my @sorted = sort { split_sort( fc($a), fc($b), 'type', 'split expr')
+} @array;
# I made changes to split_sort detailed in a moment.
With a change I made to split_sort that should work in alpha or letter is chosen for type.
After failing to come up with a list of strings where the split would return something different from a standard sort, I was about to abandon it again. Then a thought popped into my head, and it was not the Stay Puffed marshmallow man. There might be strings where numbers were on one side the potential split and alpha was on the other and someone might want the numbers sorted numerically. So, I added the left and right options. Also, since alpha (or letter) doesn't benefit from the splitting of the strings, I had those options skip the splitting.
sub split_sort {
my ($in_a, $in_b, $sort_type, $split) = @_;
if ($sort_type =~ /^(alphaletter)/) {
$in_a cmp $in_b
}
else {
$split = qr($split);
my ($numa1, $numa2) = split(/$split/, $in_a, 2);
my ($numb1, $numb2) = split(/$split/, $in_b, 2);
if ($sort_type =~ /^num/) {
$numa1 <=> $numb1  $numa2 <=> $numb2
}
elsif (fc($sort_type) eq 'left' ) {
$numa1 <=> $numb1  $numa2 cmp $numb2
}
elsif (fc($sort_type) eq 'right' ) {
$numa1 cmp $numb1  $numa2 <=> $numb2
}
}
}
Another change I made is the I changed is order of the parameters. Since the parameter $split can be ignored for alpha, I put it at the end. I prefer to put any parameter than can be ignored or undef to be at the end of the parameter list. (If two or more parameters can be undef or ignored, then I think it is best to make them $opt.)
With those changes, the POD became easier to write. It may still be incomplete, but this is what I have so far.
=pod
=encoding utf8
=head1 NAME
B<Fancy::Sort::Split> returns the expression to split the values in li
+sts for sort.
=head1 VERSION
This document describes Fancy::Sort::Split version 1.0.
=head1 SYNOPSIS
my @numbers = qw(1:2 1:02 3:4 5:78 50:89 10:5);
my @split_sorted = sort { split_sort($a, $b, 'number', ':') } @numbe
+rs;
# returns
# [
# '1:2',
# '1:02',
# '3:4',
# '5:78',
# '10:5',
# '50:89'
# ];
my @left = qw(2:a 02:a 4:a 28:a 89:a 5:a);
my @split_sorted_left = sort { split_sort($a, $b, 'left', ':') }
+ @left;
# returns
# [
# '2:a',
# '02:a',
# '4:a',
# '5:a',
# '28:a',
# '89:a'
# ];
my @right = qw(a:2 a:02 a:4 a:28 a:89 a:5);
my @split_sorted_right = sort { split_sort($a, $b, 'right', ':') }
+ @right;
# returns
# [
# 'a:2',
# 'a:02',
# 'a:4',
# 'a:5',
# 'a:28',
# 'a:89'
# ];
=head1 DESCRIPTION
Fancy::Sort::Split returns the expression to split the values in lists
+ for L<sorthttps://perldoc.perl.org/functions/sort.html> subroutines
+ using C<split_sort>. C<split_sort> has to be imported into your scri
+pt.
C<split_sort> has four required parameters. The first and second parem
+eters are C<$a> and C<$b> from C<sort> or C<$b> and C<$a> if you want
+ a descending sort. The third parameter is the expression you want to
+ split the strings by. The fourth is the type of sort you want, C<num
+ber> or C<alpha> (C<letter>).
split_sort($a, $b, 'type', 'expr');
A note of caution for the numerical sorts, when a number has a leading
+ zero (C<02>), the leading zero will be dropped. So, C<02> will be th
+e same as C<2>.
It requires Perl version 5.16.0 or better.
=head2 Numerical sort
When you have numbers on both sides of the expression, use C<number> s
+o the numbers on both sides are numerically sorted.
split_sort($a, $b, 'number', 'expr');
=head2 Numerical sort on the left
When you have numbers on the left side of the expression, use C<left>
+so the numbers on the left side are numerically sorted..
split_sort($a, $b, 'left', 'expr');
=head2 Numberial sort on the right
When you have numbers on the right side of the expression, use C<right
+> so the numbers on the right side are numerically sorted..
split_sort($a, $b, 'right', 'expr');
=head2 Alphabetical sort
When you have letters on both sides of the expression, use C<alpha> or
+ C<letter>. However, the alphabetical sort is redundant and was added
+ for completeness. The sort expression returned will be the same as C
+<$a cmp $b> for the entire string. So, for alphabetical sorts, you ma
+y omit the expression for the split.
split_sort($a, $b, 'alpha', 'expr');
split_sort($a, $b, 'letter', 'expr');
=head1 DEPENDENCIES
Fancy::Sort::Split depends on L<Exporter>.
=head1 AUTHOR
Lady Aleena
=cut
I am a bit disappointed that the alpha part did not pan out as I wanted, but I did not put much thought into it in the first place. I am fairly happy with it as it is now.
My OS is Debian 10 (Buster); my perl versions are 5.28.1 local and 5.16.3 or 5.30.0 on web host depending on the shebang.
No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
Lady Aleena
 [reply] [d/l] [select] 

"I am fairly happy with it as it is now."
If your changes cover all potential use cases, that's good.
As the original question was focused on POD,
I thought I'd just point out a couple of discrepancies.
You wrote "... the parameter $split can be ignored for alpha ...";
but, your POD has "C<split_sort> has four required parameters.".
As it stands, users won't know what fourth parameter to use for alpha types;
an additional example wouldn't hurt.
Also in that paragraph, the last two sentences are backtofront: it should be, 3rd is 'type' and 4th is 'expr'
(cf. "split_sort($a, $b, 'type', 'expr');" which immediately follows that paragraph).
&split_sort contains no implicit return so the return value will be the result of the last expression evaluated;
that will be either a <=> or cmp expression, both of which return one of 1, 0 or 1
(see "perlop: Equality Operators").
The sort itself returns a list which you have correctly assigned to an array.
The POD immediately afterwards indicates an ARRAYREF is returned:
"returns [ ... ]".
How you deal with that one is up to you.
I'd probably show split_sort(...) and indicate it returns the same as <=> and cmp,
making it useful for sort.
Then show usage with sort much as you currently have.
Then show that it returns a LIST instead of an ARRAYREF;
just changing [...] to (...) should suffice.
For your 'left' and 'right' examples, I'd mix it up a bit to give a clearer indication of how the sorting process works.
For instance, here's a couple of arbitrary examples.
IN: 10:ab 21:bb 2:bb 21:bb 2:b
OUT: 2:b 2:bb 10:ab 21:ab 21:bb
IN: bb:10 b:1 ab:10 ab:2 bb:9
OUT: ab:2 ab:10 b:1 bb:9 bb:10
Including the '2' and '02' in your original examples was I good idea.
You may want to point out that they'll keep their original order; by which, I mean:
$ perl E 'say for sort { $a <=> $b } qw{020 2 02 20}'
2
02
020
20
$ perl E 'say for sort { $a <=> $b } qw{20 02 2 020}'
02
2
20
020
Finally, as I've not seen the the actual module code, I'm guessing a bit here.
The NAME should indicate what the module provides or implements, not what it returns;
technically, it should just return a TRUE value —
it's common for the last line of code, excluding POD, to be just 1;.
Also, it's useful to know whether functions are exported by default or not.
 [reply] [d/l] [select] 

C<split_sort> has four required parameters. The first and second parem
+eters are C<$a> and C<$b> from C<sort> or C<$b> and C<$a> if you want
+ a descending sort. The third parameter is the expression you want to
+ split the strings by. The fourth is the type of sort you want, C<num
+ber> or C<alpha> (C<letter>).
and is now:
C<split_sort> has three required parameters. The first and second pare
+meters are C<$a> and C<$b> from C<sort> or C<$b> and C<$a> if you wan
+t a descending sort. The third parameter is the type of sort you want
+: C<number>, C<left>, C<right>, or C<alpha> (C<letter>). The fourth p
+arameter is the expression you want to split the strings by and can b
+e ignored for alpha (letter) sort.
I made the modification in the synopsis changing [...] to (...), the brackets came from when I copied the results from Data::Dumper.
I noted that split_sort is not exported by default in the first paragraph of the description.
I am not sure where or how to write everything else into the POD neatly.
As for the whole module, other than the normal stuff at the top and the final 1;, you've seen it. Here is the entire thing, as of right now.
package Fancy::Sort::Split;
use v5.16.0;
use strict;
use warnings;
use Exporter qw(import);
our $VERSION = '1.0';
our @EXPORT_OK = qw(split_sort);
sub split_sort {
my ($in_a, $in_b, $sort_type, $split) = @_;
if ($sort_type =~ /^(alphaletter)/) {
$in_a cmp $in_b
}
else {
$split = qr($split);
my ($numa1, $numa2) = split(/$split/, $in_a, 2);
my ($numb1, $numb2) = split(/$split/, $in_b, 2);
if ($sort_type =~ /^num/) {
$numa1 <=> $numb1  $numa2 <=> $numb2
}
elsif (fc($sort_type) eq 'left' ) {
$numa1 <=> $numb1  $numa2 cmp $numb2
}
elsif (fc($sort_type) eq 'right' ) {
$numa1 cmp $numb1  $numa2 <=> $numb2
}
else {
$in_a <=> $in_b
}
}
}
=pod
=encoding utf8
=head1 NAME
B<Fancy::Sort::Split> returns the comparison expression to split the v
+alues in lists for sort.
=head1 VERSION
This document describes Fancy::Sort::Split version 1.0.
=head1 SYNOPSIS
my @numbers = qw(1:2 1:02 3:4 5:78 50:89 10:5);
my @split_sorted = sort { split_sort($a, $b, 'number', ':') } @numbe
+rs;
# returns
# (
# '1:2',
# '1:02',
# '3:4',
# '5:78',
# '10:5',
# '50:89'
# );
my @left = qw(2:a 02:a 4:a 28:a 89:a 5:a);
my @split_sorted_left = sort { split_sort($a, $b, 'left', ':') }
+ @left;
# returns
# (
# '2:a',
# '02:a',
# '4:a',
# '5:a',
# '28:a',
# '89:a'
# );
my @right = qw(a:2 a:02 a:4 a:28 a:89 a:5);
my @split_sorted_right = sort { split_sort($a, $b, 'right', ':') }
+ @right;
# returns
# (
# 'a:2',
# 'a:02',
# 'a:4',
# 'a:5',
# 'a:28',
# 'a:89'
# );
=head1 DESCRIPTION
Fancy::Sort::Split returns the comparison expression to split the valu
+es in lists for L<sorthttps://perldoc.perl.org/functions/sort.html>
+subroutines using C<split_sort>. C<split_sort> is not exported by def
+ault and has to be imported into your script.
use Fancy::Sort::Split qw(split_sort);
C<split_sort> has three required parameters. The first and second pare
+meters are C<$a> and C<$b> from C<sort> or C<$b> and C<$a> if you wan
+t a descending sort. The third parameter is the type of sort you want
+: C<number>, C<left>, C<right>, or C<alpha> (C<letter>). The fourth p
+arameter is the expression you want to split the strings by and can b
+e ignored for alpha (letter) sort.
split_sort($a, $b, 'type', 'expr');
A note of caution for the numerical sorts, when a number has a leading
+ zero (C<02>), the leading zero will be dropped. So, C<02> will be th
+e same as C<2> and will be returned in their original order. So, C<qw
+(02 2)> and C<qw(2 02)> will be sorted in that order.
It requires Perl version 5.16.0 or better.
=head2 Numerical sort
When you have numbers on both sides of the expression, use C<number> s
+o the numbers on both sides are numerically sorted.
split_sort($a, $b, 'number', 'expr');
=head2 Numerical sort on the left
When you have numbers on the left side of the expression, use C<left>
+so the numbers on the left side are numerically sorted.
split_sort($a, $b, 'left', 'expr');
=head2 Numberial sort on the right
When you have numbers on the right side of the expression, use C<right
+> so the numbers on the right side are numerically sorted.
split_sort($a, $b, 'right', 'expr');
=head2 Alphabetical sort
When you have letters on both sides of the expression, use C<alpha> or
+ C<letter>. However, the alphabetical sort is redundant and was added
+ for completeness. The sort expression returned will be the same as C
+<$a cmp $b> for the entire string. So, for alphabetical sorts, you ma
+y omit the expression for the split.
split_sort($a, $b, 'alpha', 'expr');
split_sort($a, $b, 'letter', 'expr');
=head1 DEPENDENCIES
Fancy::Sort::Split depends on L<Exporter>.
=head1 AUTHOR
Lady Aleena
=cut
1;
My OS is Debian 10 (Buster); my perl versions are 5.28.1 local and 5.16.3 or 5.30.0 on web host depending on the shebang.
No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
Lady Aleena
 [reply] [d/l] [select] 

