Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > 'by package' sorting of fully qualified functions

Reply
Thread Tools

'by package' sorting of fully qualified functions

 
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      01-29-2004
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$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
 
Reply With Quote
 
 
 
 
Anno Siegel
Guest
Posts: n/a
 
      01-29-2004
Tassilo v. Parseval <(E-Mail Removed)-aachen.de> wrote in comp.lang.perl.misc:
> 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.


That last requirement will have to be dealt with in an ad-hoc manner.
Also, "__MAIN__" isn't a fully qualified function name. I'll ignore
it for now.

> 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;
> }


Gee, I must be missing something. As far as I see, you only need to
split off the (final) function name. Sort the package parts, and within
these sort the function names. So:

sub bypackage {
my ( $apack, $aname) = $a =~ /(.+):.+)/;
my ( $bpack, $bname) = $b =~ /(.+):.+)/;
$apack cmp $bpack or $aname cmp $bname;
}

[...]

> Bonus question: if speed was an issue, how could techniques such as
> the Schwartzian or Guttman-Rosler Transform be applied here?


I don't need to explain how to apply the Schwartz transform to my
suggestion. The GRT doesn't seem to apply easily, as always when
different sort fields must be dealt with independently.

Anno
 
Reply With Quote
 
 
 
 
Ben Morrow
Guest
Posts: n/a
 
      01-29-2004

http://www.velocityreviews.com/forums/(E-Mail Removed)-aachen.de wrote:
> 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.

<snip>
> How would others solve this task?


#!/usr/bin/perl

$\ = $, = "\n";

use subs qw/hier_cmp bypackage/;

my @functions = qw/
Pack1::subpack::func2
Pack1::subpack::func1
Pack1::func
__MAIN__
Pack2::bla
Pack1::subpack::another_subpack::func
/;

sub hier_cmp {
my @x = @{$_[0]};
my @y = @{$_[1]};

my ($x, $y) = (shift @x, shift @y);

return $x cmp $y unless @x || @y;
return 1 unless @y;
return -1 unless @x;

return ($x cmp $y) || hier_cmp \@x, \@y;
}

sub bypackage {
return 1 if $a eq '__MAIN__';
return -1 if $b eq '__MAIN__';

my @a = split /::/, $a;
my @b = split /::/, $b;

return hier_cmp \@a, \@b;
}

print sort bypackage @functions;

__END__

I don't really like having '$x cmp $y' in there twice, but I can't see
how to get rid of it.

Ben

--
If I were a butterfly I'd live for a day, / I would be free, just blowing away.
This cruel country has driven me down / Teased me and lied, teased me and lied.
I've only sad stories to tell to this town: / My dreams have withered and died.
http://www.velocityreviews.com/forums/(E-Mail Removed) <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=> (Kate Rusby)
 
Reply With Quote
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      01-29-2004
Also sprach Anno Siegel:

> Tassilo v. Parseval <(E-Mail Removed)-aachen.de> wrote in comp.lang.perl.misc:
>> 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__


[...]

> Gee, I must be missing something. As far as I see, you only need to
> split off the (final) function name. Sort the package parts, and within
> these sort the function names. So:
>
> sub bypackage {
> my ( $apack, $aname) = $a =~ /(.+):.+)/;
> my ( $bpack, $bname) = $b =~ /(.+):.+)/;
> $apack cmp $bpack or $aname cmp $bname;
> }


Embarrassingly simple really. I initially was treating the function name
in a similar matter. But the major flaw in each of my attempts was that I
also split the package portion instead of just leaving it intact.

Alright, I'll retreat in shame.

>> Bonus question: if speed was an issue, how could techniques such as
>> the Schwartzian or Guttman-Rosler Transform be applied here?

>
> I don't need to explain how to apply the Schwartz transform to my
> suggestion.


Indeed not, thank you!

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$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
 
Reply With Quote
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      01-29-2004
Also sprach Ben Morrow:

> (E-Mail Removed)-aachen.de wrote:
>> 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.

><snip>
>> How would others solve this task?

>
> #!/usr/bin/perl
>
> $\ = $, = "\n";
>
> use subs qw/hier_cmp bypackage/;
>
> my @functions = qw/
> Pack1::subpack::func2
> Pack1::subpack::func1
> Pack1::func
> __MAIN__
> Pack2::bla
> Pack1::subpack::another_subpack::func
> /;
>
> sub hier_cmp {
> my @x = @{$_[0]};
> my @y = @{$_[1]};
>
> my ($x, $y) = (shift @x, shift @y);
>
> return $x cmp $y unless @x || @y;
> return 1 unless @y;
> return -1 unless @x;
>
> return ($x cmp $y) || hier_cmp \@x, \@y;
> }
>
> sub bypackage {
> return 1 if $a eq '__MAIN__';
> return -1 if $b eq '__MAIN__';
>
> my @a = split /::/, $a;
> my @b = split /::/, $b;
>
> return hier_cmp \@a, \@b;
> }
>
> print sort bypackage @functions;
>
> __END__
>
> I don't really like having '$x cmp $y' in there twice, but I can't see
> how to get rid of it.


I kind of like that. It's the recursive implementation of what my
function did. Yet I assume that you would have come up with a solution
similar to Anno's if I hadn't provided my ridiculously complicated code
that probably distracted you.

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$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
 
Reply With Quote
 
Bo Lindbergh
Guest
Posts: n/a
 
      01-29-2004
How about this: split each fully qualified name into package name and
function name; use the package name as the key for a hash of arrays of
function names. This lets you sort the package names first and then
sort the function names within each package separately.

/Bo Lindbergh
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Pointer to qualified poitner to qualified object Szabolcs Borsanyi C Programming 13 06-08-2008 07:52 PM
javap: fully qualified names for "new" statements S.Marion Java 2 03-03-2006 01:32 AM
REPOST FormsAuthentication.RedirectFromLoginPage is not passed fully qualified url Jacob Crossley ASP .Net 0 04-06-2004 03:13 PM
FormsAuthentication.RedirectFromLoginPage is not passed fully qualified url Jacob Crossley ASP .Net 0 04-02-2004 04:04 PM
Re: fully qualified domain name Frank Drebin ASP .Net 0 08-26-2003 08:43 PM



Advertisments