use List::Util::IsSorted 'is_sorted'; print is_sorted { $a <=> $b } 1, 3, 5, 5, 8; # prints 1 #### package List::Util::IsSorted; use strict; use base 'Exporter'; use vars qw(@EXPORT_OK); @EXPORT_OK = 'is_sorted'; sub import { # prevent "used only once" warning no strict 'refs'; my $caller = caller; local *{$caller."::a"} = local *{$caller."::b"} = \0; # business as usual goto &Exporter::import; } sub is_sorted (&@) { my $code = shift; my %dir; return '0E0' unless @_ > 1; no strict 'refs'; my $caller = caller; local(*{$caller."::a"}) = \my $a; local(*{$caller."::b"}) = \my $b; $a = shift; foreach (@_) { $b = $_; $dir{0 <=> &{$code}()}++; return 0 if $dir{1} && $dir{-1}; $a = $b; } my $dir = $dir{1} ? 1 : $dir{-1} ? -1 : '0E0'; $dir <<= 1 unless $dir{0}; return $dir || '0E0'; } 1; __END__ =head1 NAME List::Util::IsSorted - Test if a list is sorted, in the style of L =head1 SYNOPSIS use List::Util::IsSorted 'is_sorted'; $sort_status = is_sorted { $a cmp $b } qw(alpha beta gamma); =head1 DESCRIPTION C contains a subroutine to test if a list is sorted according to a comparison test. =over 4 =item is_sorted BLOCK LIST Tests to see if LIST is sorted strictly ascending or descending, not-descending or not-ascending, flat, or unsorted, by calling BLOCK multiple times, setting C<$a> and C<$b> to a pair of parameter values each time. The return value is one of the following: =over 6 =item 2 strictly ascending: The list is sorted according to the rules of the code block, where each next element compares as greater than the previous one. =item 1 ascending: The list is sorted according to the rules of the code block, though some consecutive elements compare as the same. =item '0E0' flat: the list contains only elements that compare as the same. =item '0' unsorted: the list contains changes in both ways =item -1 descending: The list is sorted I to the rules of the code block, though some consecutive elements compare as the same. =item -2 strictly descending: The list is sorted opposite to the rules of the code block, where each next element compares as less than the previous one. =back =back =head1 SEE ALSO L =back =cut