Почему это объявление подпрограммы anon анализируется как метод косвенного объекта в Perl? - PullRequest
9 голосов
/ 23 января 2011

В следующем объявлении анонимной подпрограммы Perl, похоже, анализирует его как косвенный вызов метода, а не как подпрограмму:

use 5.010;
use strict;
use warnings;

sub proxy {
    my $new = shift;
    say "creating proxy: $new";
    sub :lvalue {
        say "running proxy: $new";
        tie my $ret, 'Some::Package', shift, $new;
        $ret
    }
}

say "before";
my $p1 = proxy '_value';
say "p1 declared: $p1";
my $p2 = proxy 'value';
say "p2 declared: $p2";

который печатает:

before
creating proxy: _value
running proxy: _value
Can't locate object method "TIESCALAR" via package "Some::Package" ...

Если return или my $sub = добавлено непосредственно перед sub :lvalue {..., то все работает правильно и выдает:

before
creating proxy: _value
p1 declared: CODE(0x4c7e6c)
creating proxy: value
p2 declared: CODE(0x1ea85e4)

Это также работает, если атрибут :lvalue удален из подпрограммы (но, конечно, это изменяет функциональность).

Итак, мой вопрос: почему это происходит? Это ошибка в Perl, связанная с атрибутами анонимных подпрограмм? По какой-то причине это ожидаемое поведение? Если это ошибка, она зарегистрирована?

1 Ответ

15 голосов
/ 23 января 2011

Поскольку начало оператора является допустимым местом для поиска метки goto, и поэтому голое слово sub, за которым следует маркер двоеточия, анализируется как метка sub:, за которой следует lvalue BLOCK, который анализируется как косвенный синтаксис объекта.

Если вы заставляете синтаксический анализатор искать термин, выполняя return sub : lvalue { ... } или my $foo = sub : lvalue { ... }, он анализирует по назначению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...