———use
strict;
use
warnings;
use
Moo::Role;
=head1 NAME
Articulate::Role::Sortation::AllYouNeedIsCmp - provides sortation methods derived from you cmp method
=head1 SYNOPSIS
package My::Sortation::Class;
use Moo;
with 'Articulate::Role::Sortation::AllYouNeedIsCmp';
sub cmp { ... }
sub decorate { ... } # optional
1;
Provides the C<sort> and C<schwartz> funtions. These call on the C<cmp> method (which you are exected to write) and, optionally, the C<decorate> method (if it exists).
=cut
=head1 METHODS
=head3 order
Convenience method which inspects the C<order> value of the C<options> hash and returns it (or returns C<asc>) if undefined).
=cut
sub
order {
my
$self
=
shift
;
return
(
$self
->options->{order} //
'asc'
)
if
$self
->can(
'options'
);
return
'asc'
;
}
=head3 sort
$sorter->sort( [items] )
Performs a simple sort, using C<cmp> and C<decorate>.
=cut
sub
sort
{
my
$self
=
shift
;
my
$items
=
shift
;
my
$dec
=
sub
{
my
$orig
=
shift
;
$self
->can(
'decorate'
)
?
$self
->decorate(
$orig
)
:
$orig
;
};
return
[
sort
{
$self
->cmp(
$dec
->(
$b
),
$dec
->(
$a
) ) }
@$items
]
if
'desc'
eq
$self
->order;
return
[
sort
{
$self
->cmp(
$dec
->(
$a
),
$dec
->(
$b
) ) }
@$items
];
}
=head3 schwartz
$sorter->schwartz( [items] );
Performs a schwartxian transform using C<decorate>, and sorts the decorated items using C<cmp>, then returns the originals in the sorted order.
=cut
sub
schwartz {
my
$self
=
shift
;
my
$items
=
shift
;
if
(
$self
->can(
'decorate'
) ) {
return
[
map
{
$_
->[0] }
sort
{
$self
->cmp(
$a
->[1],
$b
->[1] ) }
map
{ [
$_
,
$self
->decorate(
$_
) ] }
@$items
];
}
else
{
return
$self
->
sort
(
$items
);
}
}
1;