#!perl
#examples poached from perldoc -f sort

# sort lexically
@articles = sort @files;

# same thing, but with explicit sort routine
@articles = sort {$a cmp $b} @files;

# now case-insensitively
@articles = sort {uc($a) cmp uc($b)} @files;

# same thing in reversed order
@articles = sort {$b cmp $a} @files;

# sort numerically ascending
@articles = sort {$a <=> $b} @files;

# sort numerically descending
@articles = sort {$b <=> $a} @files;

# this sorts the %age hash by value instead of key
# using an in-line function
@eldest = sort { $age{$b} <=> $age{$a} } keys %age;

# sort using explicit subroutine name
sub byage {
    $age{$a} <=> $age{$b};  # presuming numeric
}
@sortedclass = sort byage @class;

sub backwards { $b cmp $a }
@harry  = qw(dog cat x Cain Abel);
@george = qw(gone chased yz Punished Axed);
print sort @harry;
# prints AbelCaincatdogx
print sort backwards @harry;
# prints xdogcatCainAbel
print sort @george, 'to', @harry;
# prints AbelAxedCainPunishedcatchaseddoggonetoxyz

# inefficiently sort by descending numeric compare using
# the first integer after the first = sign, or the
# whole record case-insensitively otherwise
@new = @old[ sort {
    $nums[$b] <=> $nums[$a]
	|| $caps[$a] cmp $caps[$b]
	} 0..$#old  ];

# same thing, but without any temps
@new = map { $_->[0] }
sort { $b->[1] <=> $a->[1] 
	   || $a->[2] cmp $b->[2]
	   } map { [$_, /=(\d+)/, uc($_)] } @old;

# using a prototype allows you to use any comparison subroutine
# as a sort subroutine (including other package's subroutines)
package other;
sub backwards ($$) { $_[1] cmp $_[0]; }     # $a and $b are not set here
package main;
@new = sort other::backwards @old;

# repeat, condensed. $main::a and $b are unaffected
sub other::backwards ($$) { $_[1] cmp $_[0]; }
@new = sort other::backwards @old;

# guarantee stability, regardless of algorithm
use sort 'stable';
@new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;

# force use of mergesort (not portable outside Perl 5.8)
use sort '_mergesort';
@new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;

# you should have a good reason to do this!
@articles = sort {$FooPack::b <=> $FooPack::a} @files;

# fancy
@result = sort { $a <=> $b } grep { $_ == $_ } @input;

# void return context sort
sort { $a <=> $b } @input;

# more void context, propagating ?
sort { $a <=> $b } grep { $_ == $_ } @input;

# scalar return context sort
$s = sort { $a <=> $b } @input;

$s = sort { $a <=> $b } grep { $_ == $_ } @input;

