Как использовать $a и $b в подпрограмме Perl

Я хотел бы использовать $a а также $b переменные в моих анонимных бинарных функциях, как это сделано в sort {$a <=> $b} (1, 2, 3) но я не могу понять, почему код нравится

#!/usr/bin/env perl
use strict;
use warnings;

Foo::Bar(sub { $a + $b });

package Foo;
sub Bar {
    my ($function) = @_; 

    for my $i (1, 2, 3) {
        local ($a, $b) = ($i, $i);
        print $function->() . "\n";
    }
}    

не работает. В то время как

#!/usr/bin/env perl
use strict;
use warnings;

Foo::Bar(sub { $_ });

package Foo;
sub Bar {
    my ($function) = @_; 

    for my $i (1, 2, 3) {
        local $_ = $i;
        print $function->() . "\n";
    }
}

работает отлично.

Что я делаю неправильно?

2 ответа

Решение

$a а также $b специальные переменные пакета. Ты звонишь Foo::Bar из вашего main пакет, так что вам нужно установить $main::a а также $main::b заставить его работать. Ты можешь использовать caller получить имя вызывающего пакета. Это должно работать:

#!/usr/bin/env perl
use strict;
use warnings;

Foo::Bar(sub { $a + $b });

package Foo;
sub Bar {
    my ($function) = @_; 
    my $pkg = caller;

    for my $i (1, 2, 3) {
        no strict 'refs';
        local *{ $pkg . '::a' } = \$i;
        local *{ $pkg . '::b' } = \$i;
        print $function->() . "\n";
    }
}    

На всякий случай, если кому-то интересно, скопируйте и вставьте из List:: MoreUtils:: PP v.0.428 (по состоянию на декабрь 2017 года):

# begin copyrighted content
sub reduce_u(&@)
{
    my $code = shift;

    # Localise $a, $b
    my ($caller_a, $caller_b) = do
    {
        my $pkg = caller();
        no strict 'refs';
        \*{$pkg . '::a'}, \*{$pkg . '::b'};
    };

    local (*$caller_a, *$caller_b);
    *$caller_a = \();
    for (0 .. $#_)
    {
        *$caller_b = \$_[$_];
        *$caller_a = \($code->());
    }

    ${*$caller_a};
}
# end copyrighted content

Он отличается только от образца выше в области, затронутой no strict 'refs';, Вероятно, не может быть сделано без каких-либо строгих вообще.

Другие вопросы по тегам