Question: So I have a Perl class. It has a `sort()` method, and I want it to be more or less identical to the built-in `sort()` function:

```
$object->sort(sub ($$) { $_[0] <=> $_[1] });

```

But I can't do:

```
$object->sort(sub { $a <=> $b });

```

Because of scoping. But the List::Util module does this with `reduce()`. I looked at the List::Util module, and they do some rather nasty things with `no strict 'vars'` to make this happen. I tried that, but to no avail.

It is my understanding that `reduce()` works the way it does because it is exported into the appropriate namespace, and thus my class can't do this since the function is quite firmly in another namespace. Is this correct, or is there some (undoubtedly more hideous and ill-advised) way to do this in my situation?

Answer: 
Well, the other two answers are both half-right. Here's a working solution that actually sorts:

```
package Foo;

use strict;
use warnings;

sub sort {
    my ($self, $sub) = @_;

    my ($pkg) = caller;
    my @x = qw(1 6 39 2 5);
    print "@x\n";
    {
        no strict 'refs';
        @x = sort {
            local (${$pkg.'::a'}, ${$pkg.'::b'}) = ($a, $b);
            $sub->();
        } @x;
    }
    print "@x\n";

    return;
}

package main;

use strict;
use warnings;

my $foo = {};
bless $foo, 'Foo';

$foo->sort(sub { $a <=> $b });
# 1 6 39 2 5
# 1 2 5 6 39

```

Presumably you'd sort some data that's actually part of the object.

You need the [`caller`](http://perldoc.perl.org/functions/caller.html) magic so you're localizing `$a` and `$b` in the caller's package, which is where Perl is going to look for them. It's creating global variables that only exist while that sub is being called.

Note that you will get a 'name used only once' with `warnings`; I'm sure there's some hoops you can jump through to avoid this, somehow.
You could use [Sub::Identify](http://search.cpan.org/perldoc?Sub::Identify) to find out the package (which it calls `stash_name`) associated with the coderef. Then set $a and $b in that package as required. You may need to use `no strict 'refs'` in your method to get that to work.

Here's Evee's answer modified to work in the general case:

```
use strict;
use warnings;

package Foo;

use Sub::Identify 'stash_name';

sub sort {
    my ($self, $sub) = @_;

    my $pkg = stash_name($sub);
    my @x = qw(1 6 39 2 5);
    print "@x\n";
    {
        no strict 'refs';
        @x = sort {
            local (${$pkg.'::a'}, ${$pkg.'::b'}) = ($a, $b);
            $sub->();
        } @x;
    }
    print "@x\n";

    return;
}

package Sorter;

sub compare { $a <=> $b }

package main;

use strict;
use warnings;

my $foo = {};
bless $foo, 'Foo';

$foo->sort(\&Sorter::compare );

$foo->sort(sub { $b <=> $a });

```