Внутренние изменения состояния после блока try{}

Я работаю с Marpa::R2 и пытаюсь отловить ошибки, используя Try:: Tiny. Я озадачен, потому что, когда я помещаю код разбора в try блок, результат value метод undef, Вот мой код:

use strict;
use warnings;
use Marpa::R2;
use Data::Dumper;
use Try::Tiny;

my $grammar = Marpa::R2::Scanless::G->new(
    {
        source => \(<<'END_OF_SOURCE'),
            :default ::= action => ::array
            :discard ~ ws
            ws ~ [\s]+
            :start ::= Name
            Name ::= Foo
            Foo ~ [\w]+
END_OF_SOURCE
    }
);
my $reader = Marpa::R2::Scanless::R->new(
    {
        grammar => $grammar,
    }
);
my $input = 'foo';
try{
    $reader->read(\$input);
}catch {
    warn "caught error: $_";
}
my $value = $reader->value;
print Dumper $value;

Я немного сходил с ума, пытаясь понять, что такое грамматика, а потом понял, что удаление try блок сделал значение $reader->value ненулевой. Даже если я назначу $value в пределах try блок становится undef когда блок закончен:

my $value;
try{
    $reader->read(\$input);
    $value = $reader->value;
}catch {
    warn "caught error: $_";
}
print Dumper $value;

Кажется, это означает, что если я хочу ловить ошибки с Try::TinyЯ должен поставить ВСЕ мои обработки $value в try блок, что неудобно.

Может кто-нибудь сказать мне, что вызывает это (я хотел бы объяснить, как это возможно в Perl)? И есть ли способ это исправить?

1 ответ

Решение
try{
    $reader->read(\$input);
}catch {
    warn "caught error: $_";
}                               <------ missing semicolon
my $value = $reader->value;

Имейте в виду, что try на самом деле не контрольная структура. try а также catch просто подводные лодки с &@ прототип. (Я представляю, что catch возвращает некоторую форму объекта.) Таким образом, приведенный выше код эквивалентен

&try(sub { ... }, &catch(sub { ... }, my $value = $reader->value));

Обратите внимание, как назначение $value делается до try?

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