=over =item sort SUBNAME LIST =item sort BLOCK LIST =item sort LIST Sorts the LIST and returns the sorted list value. If SUBNAME or BLOCK is omitted, Cs in standard string comparison order. If SUBNAME is specified, it gives the name of a subroutine that returns an integer less than, equal to, or greater than C<0>, depending on how the elements of the list are to be ordered. (The C<< <=> >> and C operators are extremely useful in such routines.) SUBNAME may be a scalar variable name (unsubscripted), in which case the value provides the name of (or a reference to) the actual subroutine to use. In place of a SUBNAME, you can provide a BLOCK as an anonymous, in-line sort subroutine. If the subroutine's prototype is C<($$)>, the elements to be compared are passed by reference in C<@_>, as for a normal subroutine. This is slower than unprototyped subroutines, where the elements to be compared are passed into the subroutine as the package global variables $a and $b (see example below). Note that in the latter case, it is usually counter-productive to declare $a and $b as lexicals. In either case, the subroutine may not be recursive. The values to be compared are always passed by reference, so don't modify them. You also cannot exit out of the sort block or subroutine using any of the loop control operators described in L or with C. When C is in effect, C sorts LIST according to the current collation locale. See L. Examples: # 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 = sort { ($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0] || uc($a) cmp uc($b) } @old; # same thing, but much more efficiently; # we'll build auxiliary indices instead # for speed @nums = @caps = (); for (@old) { push @nums, /=(\d+)/; push @caps, uc($_); } @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; If you're using strict, you I declare $a and $b as lexicals. They are package globals. That means if you're in the C
package, it's @articles = sort {$main::b <=> $main::a} @files; or just @articles = sort {$::b <=> $::a} @files; but if you're in the C package, it's @articles = sort {$FooPack::b <=> $FooPack::a} @files; The comparison function is required to behave. If it returns inconsistent results (sometimes saying C<$x[1]> is less than C<$x[2]> and sometimes saying the opposite, for example) the results are not well-defined. =back