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

```
You can use [the `local` operator](http://perldoc.perl.org/functions/local.html) to set values for `$a` and `$b` for the duration of the subroutine call:

```
sub sample
{
    my $callback = shift;
    for (my $i = 0; $i < @_; $i += 2) {
        local ($a, $b) = @_[$i, $i + 1];
        $callback->();
    }
}       

sample sub { print "$a $b\n" }, qw(a b c d e f g h i j);

```

If you have an ordinary subroutine, rather than a method, then you can make it be even more like `sort`, so you don't need to use `sub` before your callback function. Use a prototype on the function:

```
sub sample (&@)

```

Then you call call it like this:

```
sample { print "$a $b\n" } qw(a b c d e f g h i j);

```

Methods, though, are not influenced by prototypes.