On 22 Mar 2006 12:19:26 -0800, "David McNerney" <(E-Mail Removed)> wrote:

>I get some interesting results when I run the following code on Perl

>5.8.5 or 5.8.6:

>

>---- begin code ----

>#!/usr/bin/perl -w

>use strict;

>

>package another;

>sub testFunction

>{

> my @values = sort

> {

> print "[testFunction, sort function 1] a=$a b=$b\n";

> $a <=> $b

> } (1,2,3,4,5);

> my @values2 = sort

> {

> print "[testFunction, sort function 2] a=$a b=$b\n";

> $a <=> $b

> } (1,2,3,4,5);

>}

>

>package my_package;

>my @seqnums = (486098561006,486098561006);

>@seqnums = sort

>{

> &another::testFunction;

> return $a <=> $b;

>} @seqnums;

>-------- end code -----

>

>It seems that the second time I try to do a sort in a function/method

>invoked from within another sort, $a and $b are not defined. If I

>define a separate sort function with prototypes, the problem goes away.

>The problem also goes away if I have everything in the same package

>(ie, get rid of the 2 "package" statements and the "another::" in the

>call to &testFunction).

>

>Can anyone see something I'm doing wrong here? Needless to say, the

>above code is a minimal test case, and I'm aware that sorting

>(1,2,3,4,5) and not doing anything with the results would not normally

>be worthwhile...

Apparently theres no problem with nested sorts within a package as

you've said. Nesting between pkgs seems to fail after the first

sucessfull intra-package nested sort. Even subsequent calls fail.

The $a and $b are confined withing the package as you said as well.

Also, you mentioned

"If I define a separate sort function with prototypes, the problem goes away."

Be aware there is nested sorts are not the same as sort comparison function.

You can define your own "comparison" function that returns true of false, you

can't define a sort function that will have any local affect as in a nested

sort call. Sorts are autonomous.

The form you might be thinking of here is the "sort SUBNAME list".

From the hard to understand docs:

"# 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;

"

Note that $a and $b are not set here as it says. And it only returns t/f

based on the comparison.

This is very different from the behavior you have uncovered.

In general, intermediate $a, $b results are not usefull.

I don't know if "nesting" sorts is good for anything, it might be but

intermediate $a,$b values depend on the method and comparisons.

Nested or complex comparisons are usefull however. For instance

if $a, or $b contain a reference to multifield records where a

multi field sort is needed.

So the bottom like is you probably are just showing a behavior that

deadends in a place that is of no use and designed to fail gracefully

and without documentation. Of course $a and $b generate warnings when

they are not defined (I commented it out below).

Good find!

use strict;

#use warnings;

package another;

sub testFunction

{

my @values = sort

{

print "[testFunction, sort function 1] a=$a b=$b\n";

$a <=> $b

} (1,2,3,4,5);

my @values2 = sort

{

print "[testFunction, sort function 2] a=$a b=$b\n";

$a <=> $b

} (1,2,3,4,5);

}

package my_package;

my @seqnums = (3,2,1);

@seqnums = sort

{

&another::testFunction;

print "====== a=$a b=$b ================\n";

return $a <=> $b;

} @seqnums;

__END__

[testFunction, sort function 1] a=1 b=2

[testFunction, sort function 1] a=3 b=4

[testFunction, sort function 1] a=1 b=3

[testFunction, sort function 1] a=3 b=2

[testFunction, sort function 1] a=1 b=5

[testFunction, sort function 1] a=5 b=2

[testFunction, sort function 1] a=5 b=3

[testFunction, sort function 1] a=5 b=4

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

====== a=3 b=2 ================

[testFunction, sort function 1] a= b=

[testFunction, sort function 1] a= b=

[testFunction, sort function 1] a= b=

[testFunction, sort function 1] a= b=

[testFunction, sort function 1] a= b=

[testFunction, sort function 1] a= b=

[testFunction, sort function 1] a= b=

[testFunction, sort function 1] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

[testFunction, sort function 2] a= b=

====== a=2 b=1 ================

***************************

***************************

use strict;

#use warnings;

#package another;

sub testFunction

{

my @values = sort

{

print "[testFunction, sort function 1] a=$a b=$b\n";

$a <=> $b

} (1,2,3,4,5);

my @values2 = sort

{

print "[testFunction, sort function 2] a=$a b=$b\n";

$a <=> $b

} (1,2,3,4,5);

}

#package my_package;

my @seqnums = (3,2,1);

@seqnums = sort

{

# &another::testFunction;

&testFunction;

print "====== a=$a b=$b ================\n";

my @values = sort

{

print "[testFunction, sort function 3] a=$a b=$b\n";

$a <=> $b

} (1,2,3,4,5);

my @values2 = sort

{

print "[testFunction, sort function 4] a=$a b=$b\n";

$a <=> $b

} (1,2,3,4,5);

return $a <=> $b;

} @seqnums;

__END__

[testFunction, sort function 1] a=1 b=2

[testFunction, sort function 1] a=3 b=4

[testFunction, sort function 1] a=1 b=3

[testFunction, sort function 1] a=3 b=2

[testFunction, sort function 1] a=1 b=5

[testFunction, sort function 1] a=5 b=2

[testFunction, sort function 1] a=5 b=3

[testFunction, sort function 1] a=5 b=4

[testFunction, sort function 2] a=1 b=2

[testFunction, sort function 2] a=3 b=4

[testFunction, sort function 2] a=1 b=3

[testFunction, sort function 2] a=3 b=2

[testFunction, sort function 2] a=1 b=5

[testFunction, sort function 2] a=5 b=2

[testFunction, sort function 2] a=5 b=3

[testFunction, sort function 2] a=5 b=4

====== a=3 b=2 ================

[testFunction, sort function 3] a=1 b=2

[testFunction, sort function 3] a=3 b=4

[testFunction, sort function 3] a=1 b=3

[testFunction, sort function 3] a=3 b=2

[testFunction, sort function 3] a=1 b=5

[testFunction, sort function 3] a=5 b=2

[testFunction, sort function 3] a=5 b=3

[testFunction, sort function 3] a=5 b=4

[testFunction, sort function 4] a=1 b=2

[testFunction, sort function 4] a=3 b=4

[testFunction, sort function 4] a=1 b=3

[testFunction, sort function 4] a=3 b=2

[testFunction, sort function 4] a=1 b=5

[testFunction, sort function 4] a=5 b=2

[testFunction, sort function 4] a=5 b=3

[testFunction, sort function 4] a=5 b=4

[testFunction, sort function 1] a=1 b=2

[testFunction, sort function 1] a=3 b=4

[testFunction, sort function 1] a=1 b=3

[testFunction, sort function 1] a=3 b=2

[testFunction, sort function 1] a=1 b=5

[testFunction, sort function 1] a=5 b=2

[testFunction, sort function 1] a=5 b=3

[testFunction, sort function 1] a=5 b=4

[testFunction, sort function 2] a=1 b=2

[testFunction, sort function 2] a=3 b=4

[testFunction, sort function 2] a=1 b=3

[testFunction, sort function 2] a=3 b=2

[testFunction, sort function 2] a=1 b=5

[testFunction, sort function 2] a=5 b=2

[testFunction, sort function 2] a=5 b=3

[testFunction, sort function 2] a=5 b=4

====== a=2 b=1 ================

[testFunction, sort function 3] a=1 b=2

[testFunction, sort function 3] a=3 b=4

[testFunction, sort function 3] a=1 b=3

[testFunction, sort function 3] a=3 b=2

[testFunction, sort function 3] a=1 b=5

[testFunction, sort function 3] a=5 b=2

[testFunction, sort function 3] a=5 b=3

[testFunction, sort function 3] a=5 b=4

[testFunction, sort function 4] a=1 b=2

[testFunction, sort function 4] a=3 b=4

[testFunction, sort function 4] a=1 b=3

[testFunction, sort function 4] a=3 b=2

[testFunction, sort function 4] a=1 b=5

[testFunction, sort function 4] a=5 b=2

[testFunction, sort function 4] a=5 b=3

[testFunction, sort function 4] a=5 b=4