Sort-Fields
view release on metacpan or search on metacpan
lib/Sort/Fields.pm view on Meta::CPAN
package Sort::Fields;
use strict;
use vars qw($VERSION @EXPORT);
use Exporter qw(import);
require 5.003_03;
;
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw(
make_fieldsort
fieldsort
make_stable_fieldsort
stable_fieldsort
);
$VERSION = '1.003';
use Carp;
sub make_fieldsort {
my $selfname;
if ((caller)[0] eq 'Sort::Fields') {
($selfname) = (caller 1)[3] =~ /([^:]*)$/;
} else {
$selfname = 'make_fieldsort'
};
unless (@_) {
croak "$selfname requires argument(s)";
}
my ($sep, $cols);
if (ref $_[0]) {
$sep = '\\s+'
} else {
$sep = shift;
}
unless (ref($cols = shift) eq 'ARRAY') {
croak "$selfname field specifiers must be in anon array";
}
my (@sortcode, @col);
my $level = 1;
my $maxcol = -1;
my $stable = 0;
if (@$cols and $$cols[0] eq '-') {
shift @$cols;
$stable = 1;
}
unless (@$cols) {
croak "$selfname must have at least one field specifier";
}
for (@$cols) {
unless (/^-?\d+n?$/) {
croak "improperly formatted $selfname column specifier '$_'";
}
my ($a, $b) = /^-/ ? qw(b a) : qw(a b);
my $op = /n$/ ? '<=>' : 'cmp';
my ($col) = /^-?(\d+)/;
if ($col == 0) { # column 0 gives the entire string
push @sortcode, "\$${a}->[0] $op \$${b}->[0]";
next;
}
push @col, (/(\d+)/)[0] - 1;
$maxcol = $col[-1] if $maxcol < $col[-1];
if ($stable) {
# indices are offset by 1 in this case
my $levp1 = $level + 1;
push @sortcode, "\$${a}->[$levp1] $op \$${b}->[$levp1]";
} else {
push @sortcode, "\$${a}->[$level] $op \$${b}->[$level]";
}
$level++;
}
# have to check this all by itself, since if there's a regex
# error it won't show up until the sub is called (urk!)
eval '"" =~ /$sep/';
if ($@) {
croak "probable regexp error in $selfname arg: /$sep/\n$@";
}
my $splitfunc;
$splitfunc = eval 'sub { (split /$sep/o, $_, $maxcol + 2)[@col] } ';
if ($@) {
die "eval failed in $selfname (internal error?)\n$@";
( run in 0.565 second using v1.01-cache-2.11-cpan-140bd7fdf52 )