I have a function for case insensitive sorting. It works if it's from the same package, but not otherwise.
This works:
my @arr = sort {lc $a cmp lc $b} @list;
This works (if a function called "isort" is defined in the same file):
my @arr = sort isort @list;
This does not (function exported with Exporter from another package):
my @arr = sort isort @list;
This does not (function referred to explicitly by package name):
my @arr = sort Utils::isort @list;
What is going on? How do I put a sorting function in another package?
What evidence do you have for it not working? Have you put a print() statement in the subroutine to see if it's being called?
I suspect you're being tripped up by this (from perldoc -f sort):
$aand$bare set as package globals in the package the sort() is called from. That means$main::aand$main::b(or$::aand$::b) in themainpackage,$FooPack::aand$FooPack::bin theFooPackpackage, etc.
Oh, and later on it's more specific:
Sort subroutines written using
$aand$bare bound to their calling package. It is possible, but of limited interest, to define them in a different package, since the subroutine must still refer to the calling package's$aand$b:package Foo; sub lexi { $Bar::a cmp $Bar::b } package Bar; ... sort Foo::lexi ...Use the prototyped versions (see above) for a more generic alternative.
The "prototyped versions" are described above like this:
If the subroutine's prototype is
($$), the elements to be compared are passed by reference in@_, as for a normal subroutine. This is slower than unprototyped subroutines, where the elements to be compared are passed into the subroutine as the package global variables$aand$b(see example below).
So you could try rewriting your subroutine like this:
package Utils;
sub isort ($$) {
  my ($a, $b) = @_;
  # existing code...
}
And then calling it using one of your last two alternatives.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With