'by package' sorting of fully qualified functions

From: Tassilo v. Parseval (tassilo.parseval_at_rwth-aachen.de)
Date: 01/29/04


Date: 29 Jan 2004 09:35:39 GMT

Hi there,

I was in the situation to come up with a kind of special sort routine.
The data to be sorted is a list of fully qualified function names as in

    Pack1::subpack::func2
    Pack1::subpack::func1
    Pack1::func
    __MAIN__
    Pack2::bla
    Pack1::subpack::another_subpack::func

which ultimately should be sorted like this:

    Pack1::func
    Pack1::subpack::func1
    Pack1::subpack::func2
    Pack1::subpack::another_subpack::func
    Pack2::bla
    __MAIN__

So essentially this should order these functions hierarchicly on their
package name and finally on their function name. '__MAIN__' should
always come as last element.

I had a hard time getting it right for a seemingly simple problem such
as this one. My solution:

    @sorted = sort bypackage @functions;
    
    sub bypackage {
       
        # make sure that __MAIN__ is always last on output
        return 1 if $a eq '__MAIN__';
        return -1 if $b eq '__MAIN__';

        my @a = split /::/, $a;
        my @b = split /::/, $b;
        
        my $s = '$a[0] cmp $b[0]';
        if (@a == @b) {
            $s .= "||\$a[$_] cmp \$b[$_]" for 1 .. $#a;
        } else {
            my $min = @a < @b ? $#a : $#b;
            $s = '$a[0] cmp $b[0]';
            $s .= "||\$a[$_] cmp \$b[$_]" for 1 .. $min-1;
            $s .= "||\@a <=> \@b";
        }
        return eval $s;
    }

I am not so much concerned with the dog-like slowness of the above. That
can be tolerated (the splits could be be cached to improve it a little).
I think the wordiness doesn't make this a very elegant solution measured
by Perl-standards.

How would others solve this task?
    
Bonus question: if speed was an issue, how could techniques such as
the Schwartzian or Guttman-Rosler Transform be applied here?

Tassilo

-- 
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval


Relevant Pages