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