Какой смысл 'использования Вар' в этой подпрограмме Perl?

В одной из глав в Освоении Perl brian d foy показывает этот отрывок из Списка:: Util:

sub reduce(&@) {
    my $code = shift;
    no strict "refs";
    return shift unless @_ > 1;
    use vars qw($a $b);
    my $caller = caller;
    local(*{$caller . "::a"}) = \my $a;
    local(*{$caller . "::b"}) = \my $b;
    $a = shift;
    foreach(@_) {
        $b = $_;
        $a = &{$code}();
    }
    $a;
}

Я не понимаю какой смысл use vars qw($a $b) строка. Даже если я комментирую это, я получаю тот же вывод и предупреждения.

10
задан brian d foy 22 February 2010 в 00:37
поделиться

3 ответа

Это сделано потому, что List :: Util внутренне использует функцию reduce ().

В отсутствие use vars при использовании функции выдается следующее предупреждение:

Name "List::MyUtil::a" used only once: possible typo at a.pl line 35.
Name "List::MyUtil::b" used only once: possible typo at a.pl line 35.

Вы можете убедиться в этом сами, запустив следующий код:

use strict;
use warnings;

package List::MyUtil;

sub reduce (&@) {
   # INSERT THE TEXT FROM SUBROUTINE HERE - deleted to save space in the answer
}

sub x {
    return reduce(sub {$a+$b}, 1,2,3);
}

package main;
my $res = List::MyUtil::x();
print "$res\n";

И затем снова запустив его. при использование переменных отключено.

11
ответ дан 3 December 2019 в 23:49
поделиться

Как отмечает DVK, если мы запустим код с закомментированными use vars , мы получим предупреждение о том, что переменные используются только один раз.

Другой способ подавить предупреждение - на стороне вызывающего абонента, то есть в вызове reduce , а не в функции reduce . Это необходимо делать при использовании функций из List :: Util или List :: MoreUtils , которые принимают ссылки на код (например, попарно ). Оба этих подхода работают на стороне вызывающего абонента:

my @sums = pairwise { no warnings 'once'; $a + $b } @x, @y;

my @sums = pairwise { our($a, $b);        $a + $b } @x, @y;
2
ответ дан 3 December 2019 в 23:49
поделиться

Может быть, в это время параметр null ?

-121--3003400-

В абзаце сразу после этого кода объясняется. Существует сочетание пакетных и лексических переменных в одной области:

Остальная часть сокращения работает как сортировка, помещая два элемента в пакетные переменные $ a и $ b. Грэм определяет лексические переменные с этими именами и немедленно назначает typeglobs для $ a и $ b в вызывающем пакете с помощью символьных ссылок. После этого значения $ a и $ b являются лексическими версиями. Когда он вызывает аргумент подпрограммы & {$ code} (), этот код просматривает переменные пакета, которые действуют, когда я написал подпрограмму. Понял? Внутри уменьшите, я использую лексические версии, но внутри $ code, я использую версии пакета из вызывающего пакета. Вот почему Грэм сделал им псевдонимы друг друга.

0
ответ дан 3 December 2019 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: