6

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?

felwithe
  • 2,683
  • 2
  • 23
  • 38

1 Answers1

5

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):

$a and $b are set as package globals in the package the sort() is called from. That means $main::a and $main::b (or $::a and $::b ) in the main package, $FooPack::a and $FooPack::b in the FooPack package, etc.

Oh, and later on it's more specific:

Sort subroutines written using $a and $b are 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 $a and $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 $a and $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.

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • It works. Thanks. Pretty surprised I couldn't find this on the first page of Google or Stack Overflow results. I was all out of sorts. – felwithe Dec 09 '19 at 16:34
  • @felwithe: For some reason, good Perl advice often doesn't rank well on Google. But you can always go directly to the [official documentation site](https://perldoc.perl.org/). – Dave Cross Dec 09 '19 at 17:10