Sort a file based on values from the file name

Sort a file based on values from the file name.  We had a task were we need to process a number of files in a certain order.  This order was run, district, copy, copy total.  This code is from tobyink.  You rock!


use strict;
use warnings;
use Data::Dumper;

# sort by run then by dist then by copy then by total 
#                     run                                                                             distict copy of total
#                       |                                                                                      |    |  |

my @files = qw(
# These constants make the code below more readable.
use constant {
    IX_FILENAME => 0,
    IX_RUN      => 1,
    IX_DISTRICT => 2,
    IX_COPY     => 3,
    IX_TOTAL    => 4,

# Read this bit from bottom to top:
my @sorted =
    # Now we've sorted our arrayrefs by the fields we're interested in
    # we loop through them again, pulling out just the filename and
    # discarding the other parts.
    map {
    # Sort by the fields we're interested in. Note that if the two
    # values for RUN are different, this will sort by them, and everything
    # following the first 'or' is ignored. If they're the same, that
    # comparison returns 0, so the stuff after 'or' isn't ignored,
    # and we compare by DISTRICT, then COPY, then TOTAL.
    sort {
        $a->[IX_RUN]      <=> $b->[IX_RUN]       or
        $a->[IX_DISTRICT] <=> $b->[IX_DISTRICT]  or
        $a->[IX_COPY]     <=> $b->[IX_COPY]      or
        $a->[IX_TOTAL]    <=> $b->[IX_TOTAL]        
    # For each filename, split it into an arrayref, so that the first
    # element in the arrayref is the filename itself, and the rest are
    # the fields we're interested in.
    map {
        [ $_, m/\A[A-Z0-9]+_(\d{4})+_ETS.*_(\d{6})_(\d{2})_(\d{2})/i ]
    # Take our list of filenames…

# Check it works. (It does.)
print Dumper(\@sorted);